最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)PDF批量處理之合并、拆分、加水印的技術(shù)方案與實(shí)踐

 更新時(shí)間:2026年02月11日 09:36:07   作者:用戶3891775626958  
在日常開發(fā)中,PDF文檔處理是一個(gè)高頻需求,無論是合同管理系統(tǒng)需要合并多份PDF,還是報(bào)表系統(tǒng)需要按頁拆分,亦或是給機(jī)密文檔添加水印,都需要一套可靠的PDF處理方案,本文將分享基于Java技術(shù)棧實(shí)現(xiàn)PDF批量處理的核心思路與代碼實(shí)踐,需要的朋友可以參考下

一、技術(shù)選型

Java生態(tài)中處理PDF的庫主要有以下幾個(gè):

| 庫名 | 特點(diǎn) | 適用場景 |

|------|------|----------|

| Apache PDFBox | 開源免費(fèi),功能全面 | 合并、拆分、水印、文本提取 |

| iText | 功能強(qiáng)大,商用需授權(quán) | 復(fù)雜PDF生成、表單處理 |

| OpenPDF | iText的開源分支 | 輕量級PDF生成 |

綜合考慮開源協(xié)議和功能覆蓋度,Apache PDFBox 是大多數(shù)項(xiàng)目的首選。

二、Maven依賴配置

<dependency>

<groupId>org.apache.pdfbox</groupId>

<artifactId>pdfbox</artifactId>

<version>2.0.27</version>

</dependency>

三、PDF合并實(shí)現(xiàn)

3.1 核心思路

PDF合并的本質(zhì)是將多個(gè)PDF文檔的頁面按順序追加到一個(gè)新文檔中。PDFBox提供了PDFMergerUtility工具類來簡化這個(gè)過程。

3.2 代碼實(shí)現(xiàn)

import org.apache.pdfbox.multipdf.PDFMergerUtility;

import java.io.*;

import java.util.List;

  


public class PdfMergeService {

  


/**

* 合并多個(gè)PDF文件

* @param inputStreams PDF文件輸入流列表

* @param outputPath 輸出文件路徑

*/

public void mergePdf(List<InputStream> inputStreams, String outputPath)

throws IOException {

PDFMergerUtility merger = new PDFMergerUtility();

merger.setDestinationFileName(outputPath);

  


for (InputStream is : inputStreams) {

merger.addSource(is);

}

  


// 執(zhí)行合并,MemoryUsageSetting可控制內(nèi)存使用

merger.mergeDocuments(

org.apache.pdfbox.io.MemoryUsageSetting.setupMainMemoryOnly()

);

}

}

3.3 注意事項(xiàng)

  • 內(nèi)存管理:處理大文件時(shí)建議使用setupTempFileOnly()將臨時(shí)數(shù)據(jù)寫入磁盤,避免OOM
  • 文件順序:合并順序取決于addSource的調(diào)用順序,前端可通過拖拽排序來控制
  • 書簽處理:合并后原有書簽可能丟失,如需保留需額外處理PDDocumentOutline

四、PDF拆分實(shí)現(xiàn)

4.1 按頁碼范圍拆分

import org.apache.pdfbox.multipdf.Splitter;

import org.apache.pdfbox.pdmodel.PDDocument;

  


public class PdfSplitService {

  


/**

* 按頁碼范圍拆分PDF

* @param inputStream 源PDF輸入流

* @param startPage 起始頁(從1開始)

* @param endPage 結(jié)束頁

*/

public byte[] splitByPageRange(InputStream inputStream,

int startPage, int endPage) throws IOException {

  


try (PDDocument document = PDDocument.load(inputStream);

PDDocument newDoc = new PDDocument()) {

  


int totalPages = document.getNumberOfPages();

// 參數(shù)校驗(yàn)

startPage = Math.max(1, startPage);

endPage = Math.min(totalPages, endPage);

  


for (int i = startPage - 1; i < endPage; i++) {

newDoc.addPage(document.getPage(i));

}

  


ByteArrayOutputStream baos = new ByteArrayOutputStream();

newDoc.save(baos);

return baos.toByteArray();

}

}

}

4.2 性能優(yōu)化建議

對于頁數(shù)很多的PDF(如上千頁),逐頁操作可能較慢??梢钥紤]:

  • 使用Splitter類的setSplitAtPage()方法按固定頁數(shù)批量拆分
  • 對于僅需提取少量頁面的場景,直接操作頁面樹比使用Splitter更高效

五、PDF加水印實(shí)現(xiàn)

5.1 文字水印核心代碼

import org.apache.pdfbox.pdmodel.*;

import org.apache.pdfbox.pdmodel.font.PDType1Font;

import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;

import org.apache.pdfbox.util.Matrix;

  


public class PdfWatermarkService {

  


public byte[] addTextWatermark(InputStream input, String text,

float opacity, float rotation, float fontSize) throws IOException {

  


try (PDDocument document = PDDocument.load(input)) {

// 遍歷每一頁添加水印

for (PDPage page : document.getPages()) {

PDPageContentStream cs = new PDPageContentStream(

document, page,

PDPageContentStream.AppendMode.APPEND, true, true

);

  


// 設(shè)置透明度

PDExtendedGraphicsState gs = new PDExtendedGraphicsState();

gs.setNonStrokingAlphaConstant(opacity);

cs.setGraphicsStateParameters(gs);

  


// 設(shè)置字體和顏色

cs.setFont(PDType1Font.HELVETICA_BOLD, fontSize);

cs.setNonStrokingColor(200, 200, 200); // 淺灰色

  


// 計(jì)算頁面中心位置

float pageWidth = page.getMediaBox().getWidth();

float pageHeight = page.getMediaBox().getHeight();

float cx = pageWidth / 2;

float cy = pageHeight / 2;

  


// 旋轉(zhuǎn)變換

cs.beginText();

Matrix matrix = Matrix.getRotateInstance(

Math.toRadians(rotation), cx, cy

);

cs.setTextMatrix(matrix);

cs.showText(text);

cs.endText();

cs.close();

}

  


ByteArrayOutputStream baos = new ByteArrayOutputStream();

document.save(baos);

return baos.toByteArray();

}

}

}

5.2 中文水印的坑

PDFBox默認(rèn)的PDType1Font不支持中文字符,直接使用會導(dǎo)致亂碼或報(bào)錯(cuò)。解決方案:

// 加載系統(tǒng)中文字體

PDType0Font chineseFont = PDType0Font.load(document,

new FileInputStream("/usr/share/fonts/wqy-microhei/wqy-microhei.ttc"), 0);

cs.setFont(chineseFont, fontSize);

服務(wù)器部署時(shí)需確保安裝了中文字體

# CentOS/RHEL

sudo yum install -y wqy-microhei-fonts

# Ubuntu/Debian

sudo apt-get install -y fonts-wqy-microhei

六、封裝為REST API

在Spring Boot項(xiàng)目中,可以將上述功能封裝為統(tǒng)一的REST接口:

@RestController

@RequestMapping("/api/document/pdf")

public class PdfController {

  


@PostMapping("/merge")

public ResponseEntity<?> merge(

@RequestParam("files") MultipartFile[] files) {

// 調(diào)用合并服務(wù)

}

  


@PostMapping("/split")

public ResponseEntity<?> split(

@RequestParam("file") MultipartFile file,

@RequestParam("startPage") int startPage,

@RequestParam("endPage") int endPage) {

// 調(diào)用拆分服務(wù)

}

  


@PostMapping("/watermark")

public ResponseEntity<?> watermark(

@RequestParam("file") MultipartFile file,

@RequestParam("text") String text,

@RequestParam(defaultValue = "0.5") float opacity) {

// 調(diào)用水印服務(wù)

}

}

七、實(shí)際效果

如果你不想自己搭建服務(wù),也可以直接使用現(xiàn)成的在線工具來處理PDF。比如 輕語API開放平臺 提供了免費(fèi)的 PDF在線處理工具,支持合并、拆分、加水印、轉(zhuǎn)Word、轉(zhuǎn)圖片等功能,底層就是基于上述技術(shù)方案實(shí)現(xiàn)的。

對于需要批量處理的場景,也可以通過API接口集成到自己的系統(tǒng)中,省去重復(fù)造輪子的成本。

八、總結(jié)

| 功能 | 核心類/方法 | 難點(diǎn) |

|------|------------|------|

| PDF合并 | PDFMergerUtility | 大文件內(nèi)存管理 |

| PDF拆分 | PDDocument.getPage() | 頁碼邊界校驗(yàn) |

| PDF水印 | PDPageContentStream | 中文字體支持 |

PDF處理看似簡單,但在生產(chǎn)環(huán)境中需要關(guān)注內(nèi)存控制、字體兼容、并發(fā)處理等問題。希望本文的實(shí)踐經(jīng)驗(yàn)?zāi)軒椭闵俨纫恍┛印?/p>

以上就是Java實(shí)現(xiàn)PDF批量處理之合并、拆分、加水印的技術(shù)方案與實(shí)踐的詳細(xì)內(nèi)容,更多關(guān)于Java批量處理PDF文檔的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Graceful Response 構(gòu)建 Spring Boot 響應(yīng)處理的方法

    Graceful Response 構(gòu)建 Spring Boot 響應(yīng)

    Graceful Response是一個(gè)Spring Boot技術(shù)棧下的優(yōu)雅響應(yīng)處理器,提供一站式統(tǒng)一返回值封裝、全局異常處理、自定義異常錯(cuò)誤碼等功能,本文介紹Graceful Response 構(gòu)建 Spring Boot 下優(yōu)雅的響應(yīng)處理,感興趣的朋友一起看看吧
    2024-01-01
  • 詳解Java泛型中類型擦除問題的解決方法

    詳解Java泛型中類型擦除問題的解決方法

    Java泛型的實(shí)現(xiàn)是不完整的,有時(shí)會遇到一些Java泛型類型擦除的問題。本文將詳細(xì)為大家講解Java泛型中類型擦除問題的解決方法,需要的可以參考一下
    2022-05-05
  • IDEA 中創(chuàng)建SpringBoot 父子模塊的實(shí)現(xiàn)

    IDEA 中創(chuàng)建SpringBoot 父子模塊的實(shí)現(xiàn)

    這篇文章主要介紹了IDEA 中創(chuàng)建SpringBoot 父子模塊的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java后臺開發(fā)之表單提交之前驗(yàn)證

    Java后臺開發(fā)之表單提交之前驗(yàn)證

    這篇文章主要介紹了Java后臺開發(fā)之表單提交之前驗(yàn)證的實(shí)現(xiàn)代碼,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-02-02
  • Java日期格式化實(shí)現(xiàn)過程

    Java日期格式化實(shí)現(xiàn)過程

    本文介紹了在Java中處理日期格式y(tǒng)yyyMMddHHmmss的方法,包括使用java.time包(Java8+)和SimpleDateFormat(Java7及以下),詳細(xì)說明了格式化和解析時(shí)間的示例代碼,并強(qiáng)調(diào)了線程安全和異常處理的重要性,還討論了常見錯(cuò)誤及其解決方法,以及如何生成唯一標(biāo)識符
    2025-11-11
  • Idea中g(shù)it的使用小結(jié)

    Idea中g(shù)it的使用小結(jié)

    這篇文章主要介紹了Idea中g(shù)it的使用小結(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-01-01
  • Java基礎(chǔ)知識之Java語言概述

    Java基礎(chǔ)知識之Java語言概述

    這篇文章主要介紹了Java基礎(chǔ)知識之Java語言概述,本文介紹了Java語言相關(guān)的基礎(chǔ)知識、歷史介紹、主要應(yīng)用方向等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • 詳解spring mvc4使用及json 日期轉(zhuǎn)換解決方案

    詳解spring mvc4使用及json 日期轉(zhuǎn)換解決方案

    本篇文章主要介紹了spring mvc4使用及json 日期轉(zhuǎn)換解決方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • Java8中Map常用的遍歷方式

    Java8中Map常用的遍歷方式

    這篇文章主要給大家介紹了關(guān)于Java8中Map常用的遍歷方式,map屬于java中的頂級接口之一,區(qū)別于list,map是鍵值對的形式存在,需要的朋友可以參考下
    2023-07-07
  • Java編碼摘要算法實(shí)例解析

    Java編碼摘要算法實(shí)例解析

    這篇文章主要介紹了Java編碼摘要算法實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01

最新評論

东乌珠穆沁旗| 友谊县| 道真| 曲阳县| 英吉沙县| 张掖市| 招远市| 陆良县| 申扎县| 襄城县| 浦城县| 怀集县| 仁化县| 徐州市| 罗山县| 诏安县| 定陶县| 广汉市| 武鸣县| 萨嘎县| 同仁县| 湘潭市| 缙云县| 呼玛县| 康定县| 即墨市| 堆龙德庆县| 临城县| 花垣县| 喀什市| 阿拉善右旗| 遂溪县| 巨野县| 塔城市| 河间市| 莎车县| 四子王旗| 三都| 册亨县| 潮安县| 敦煌市|