前言
博主介紹:?目前全網(wǎng)粉絲2W+,csdn博客專家、Java領(lǐng)域優(yōu)質(zhì)創(chuàng)作者,博客之星、阿里云平臺(tái)優(yōu)質(zhì)作者、專注于Java后端技術(shù)領(lǐng)域。
涵蓋技術(shù)內(nèi)容:Java后端、算法、分布式微服務(wù)、中間件、前端、運(yùn)維、ROS等。
博主所有博客文件目錄索引:博客目錄索引(持續(xù)更新)
視頻平臺(tái):b站-Coder長(zhǎng)路
源碼獲取
項(xiàng)目源碼:Gitee、Github
本篇文檔的視頻系列講解:Java實(shí)現(xiàn)自動(dòng)化pdf打水印工具 開源PDF工具PDFBoxWord、Word轉(zhuǎn)PDF開源工具Documents4j
一、認(rèn)識(shí)PDFBox
Apache PDFBox庫是一個(gè)開源的Java工具,專門用于處理PDF文檔。它允許用戶創(chuàng)建全新的PDF文件,編輯現(xiàn)有的PDF文檔,以及從PDF文件中提取內(nèi)容。
功能:創(chuàng)建、渲染、打印、合并、拆分、加密、解密、簽名等多種操作PDF文件的功能,包括一個(gè)命令行工具,可以用于執(zhí)行各種PDF處理任務(wù)。支持文本提取和搜索,以及將PDF轉(zhuǎn)換為其他格式,如圖片和文本。
應(yīng)用場(chǎng)景:廣泛應(yīng)用于企業(yè)和開發(fā)者構(gòu)建PDF處理相關(guān)的應(yīng)用程序和工具。
Apache PDFBox具備以下主要功能:
- 從PDF文件中提取Unicode文本。
- 將單個(gè)PDF文件拆分成多個(gè)文件,或?qū)⒍鄠€(gè)PDF文件合并成一個(gè)。
- 從PDF表單中提取數(shù)據(jù),或填寫PDF表單。
- 驗(yàn)證PDF文件是否符合PDF/A-1b標(biāo)準(zhǔn)。
- 使用標(biāo)準(zhǔn)的Java打印API打印PDF文件。
- 將PDF文件另存為圖像格式,如PNG或JPEG。
- 從零開始創(chuàng)建PDF文件,包括嵌入字體和圖像。
- 對(duì)PDF文件進(jìn)行數(shù)字簽名。
二、導(dǎo)入依賴
<dependencies>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.28</version>
</dependency>
</dependencies>
三、基礎(chǔ)功能
demo1:讀取pdf所有內(nèi)容
package com.changlu.demos;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import java.io.File;
import java.net.URLDecoder;
/**
* @Description:
* @Author: changlu
* @Date: 1:28 PM
*/
public class Demo1 {
public static void main(String[] args) throws Exception{
//讀取resources目錄下input.pdf文件
String inputFile = URLDecoder.decode(Demo1.class.getClassLoader().getResource("input.pdf").getFile(), "UTF-8");
PDDocument pdDocument = PDDocument.load(new File(inputFile));
PDFTextStripper pdfTextStripper = new PDFTextStripper();
//讀取pdf中所有的文件
String fullText = pdfTextStripper.getText(pdDocument);
System.out.println(fullText);
}
}
demo2:讀取所有頁內(nèi)容(分頁)
package com.changlu;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import java.io.InputStream;
/**
* @Description:
* @Author: changlu
* @Date: 11:19 AM
*/
public class Main {
public static void main(String[] args) throws Exception{
//讀取resources目錄下input.pdf文件
InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
PDDocument pdDocument = PDDocument.load(is);
PDFTextStripper pdfTextStripper = new PDFTextStripper();
//讀取所有的分頁
for (int i = 1; i <= pdDocument.getNumberOfPages(); i++) {
//設(shè)置起始-結(jié)束頁 這里設(shè)置指定某頁
pdfTextStripper.setStartPage(i);
pdfTextStripper.setEndPage(i);
//讀取每一頁
String pageText = pdfTextStripper.getText(pdDocument);
System.out.println(String.format("第%s頁讀取內(nèi)容:", i));
System.out.println(pageText);
}
}
}
demo3:添加頁眉、頁腳
要求:頁眉頁腳居中顯示。
package com.changlu.demos;
import com.changlu.Main;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @Description: 添加頁眉、頁腳
* @Author: changlu
* @Date: 1:38 PM
*/
public class Demo3 {
public static void main(String[] args) throws Exception{
//讀取resources目錄下input.pdf文件
InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
PDDocument pdDocument = PDDocument.load(is);
//自定義字體 C:\Users\93997\Desktop\watermark tools\watermarkTools\target\classes\ttfs
//URLDecoder.decode() 方法來解碼 URL 編碼的路徑,將 %20 轉(zhuǎn)換回空格
String fontFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "ttfs" + File.separator + "Alibaba_PuHuiTi_2.0_65_Medium_65_Medium.ttf").getFile(), "UTF-8");
PDType0Font font = PDType0Font.load(pdDocument, new File(fontFile));
float fontSize = 10; // 設(shè)置字體大小為12
// 設(shè)置透明度狀態(tài)對(duì)象
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(0.2f);
graphicsState.setAlphaSourceFlag(true);
graphicsState.setStrokingAlphaConstant(0.2f);
//設(shè)置新的頁眉
String headerText = "咨詢專轉(zhuǎn)本默默學(xué)課程聯(lián)系官方報(bào)名處QQ:3503851091,更多資料可加群828303961";
String footerText = "江蘇專轉(zhuǎn)本公眾號(hào):專轉(zhuǎn)本智慧樹";
//遍歷原先的pdf文檔
for (PDPage page : pdDocument.getPages()) {
float pageWidth = page.getMediaBox().getWidth();
//計(jì)算頁眉的居中位置
float headerTextWidth = font.getStringWidth(headerText) / 1000 * fontSize;
float headerCenteredX = (pageWidth - headerTextWidth) / 2; // 計(jì)算水平居中位置
//計(jì)算頁腳的居中位置
float footerTextWidth = font.getStringWidth(footerText) / 1000 * fontSize;
float footerCenteredX = (pageWidth - footerTextWidth) / 2; // 計(jì)算水平居中位置
// 創(chuàng)建用于頁眉的內(nèi)容流
PDPageContentStream headerContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
headerContentStream.beginText(); // 開始文本操作
headerContentStream.setFont(font, fontSize); // 設(shè)置字體和字號(hào)
headerContentStream.newLineAtOffset(headerCenteredX, page.getMediaBox().getHeight() - 30); // 設(shè)置文本起始位置
headerContentStream.showText(headerText); // 繪制頁眉內(nèi)容
headerContentStream.endText(); // 結(jié)束文本操作
headerContentStream.close(); // 關(guān)閉內(nèi)容流
// 添加頁腳
PDPageContentStream footerContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
footerContentStream.beginText(); // 開始文本操作
footerContentStream.setFont(font, fontSize); // 設(shè)置字體和字號(hào)
footerContentStream.newLineAtOffset(footerCenteredX, 30); // 設(shè)置文本起始位置
footerContentStream.showText(footerText); // 繪制頁腳內(nèi)容
footerContentStream.endText(); // 結(jié)束文本操作
footerContentStream.close(); // 關(guān)閉內(nèi)容流
}
//目標(biāo)目錄 Thread.currentThread().getContextClassLoader().getResource("").getPath() 當(dāng)前工程目錄路徑
//String targetPDFPath = URLDecoder.decode(Demo3.class.getClassLoader().getResource("resources").getPath() + File.separator + "output.pdf", "UTF-8");
// String targetPDFPath = URLDecoder.decode(Main.class.getClassLoader().getResource("output.pdf").getFile(), "UTF-8");
String targetPDFPath = "F:\\00核心知識(shí)、成果、視頻產(chǎn)出區(qū)\\技術(shù)視頻\\2024.2.15 自制默默學(xué)打水印工具 watermark tools\\watermarkTools\\src\\main\\resources\\output.pdf";
File outputFile = new File(targetPDFPath);
// 若是文件存在先進(jìn)行刪除
Files.deleteIfExists(Paths.get(outputFile.toURI()));
// 保存修改后的文檔
pdDocument.save(outputFile);
System.out.println("轉(zhuǎn)換任務(wù):" + targetPDFPath + " 成功!");
// 關(guān)閉文檔
pdDocument.close(); // 關(guān)閉文檔
}
}
效果:
demo4:添加居中45°文字水印
要求:對(duì)pdf每頁都添加上旋轉(zhuǎn)45°水印,透明度為20%。
package com.changlu.demos;
import com.changlu.Main;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import java.io.File;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @Description: Apache PDFBox案例:對(duì)pdf每頁都添加上旋轉(zhuǎn)45°水印。
* @Author: changlu
* @Date: 1:38 PM
*/
public class Demo4 {
public static void main(String[] args) throws Exception{
//讀取resources目錄下input.pdf文件
InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
PDDocument pdDocument = PDDocument.load(is);
//自定義字體 C:\Users\93997\Desktop\watermark tools\watermarkTools\target\classes\ttfs
//URLDecoder.decode() 方法來解碼 URL 編碼的路徑,將 %20 轉(zhuǎn)換回空格
String fontFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "ttfs" + File.separator + "Alibaba_PuHuiTi_2.0_65_Medium_65_Medium.ttf").getFile(), "UTF-8");
PDType0Font font = PDType0Font.load(pdDocument, new File(fontFile));
// 設(shè)置透明度狀態(tài)對(duì)象
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(0.2f);
graphicsState.setAlphaSourceFlag(true);
graphicsState.setStrokingAlphaConstant(0.2f);
//設(shè)置水印名
String waterText = "江蘇專轉(zhuǎn)本網(wǎng)課報(bào)名vx:mmxchanglu";
//遍歷原先的pdf文檔
for (PDPage page : pdDocument.getPages()) {
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
//添加水印 要求:旋轉(zhuǎn)45°,不透明度30%
float waterTextWidth = font.getStringWidth(waterText) / 1000 * 30;
float waterCenteredX = (pageWidth - waterTextWidth) / 2;
float waterCenteredY = pageHeight / 2;
//創(chuàng)建一個(gè)水印內(nèi)容流
PDPageContentStream waterContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
waterContentStream.beginText();
waterContentStream.setFont(font, 30);
// 設(shè)置不透明度
waterContentStream.setNonStrokingColor(0, 0, 0); // black color
waterContentStream.setStrokingColor(0, 0, 0); // black color
waterContentStream.setGraphicsStateParameters(graphicsState);//設(shè)置透明度
//設(shè)置旋轉(zhuǎn)文本 45° 對(duì)于tx、ty是以左下角為偏移位置中心來進(jìn)行旋轉(zhuǎn)角度
waterContentStream.setTextRotation(Math.toRadians(45), 400, -50);
//設(shè)置文本
waterContentStream.newLineAtOffset(waterCenteredX, waterCenteredY);
waterContentStream.showText(waterText);
waterContentStream.endText();
waterContentStream.close();
}
//目標(biāo)目錄 Thread.currentThread().getContextClassLoader().getResource("").getPath() 當(dāng)前工程目錄路徑
String targetPDFPath = "F:\\00核心知識(shí)、成果、視頻產(chǎn)出區(qū)\\技術(shù)視頻\\2024.2.15 自制默默學(xué)打水印工具 watermark tools\\watermarkTools\\src\\main\\resources\\output.pdf";
File outputFile = new File(targetPDFPath);
// 若是文件存在先進(jìn)行刪除
Files.deleteIfExists(Paths.get(outputFile.toURI()));
// 保存修改后的文檔
pdDocument.save(outputFile);
System.out.println("轉(zhuǎn)換任務(wù):" + targetPDFPath + " 成功!");
// 關(guān)閉文檔
pdDocument.close(); // 關(guān)閉文檔
}
}
效果:
demo5:添加圖片到右上角
要求:將圖片縮小25%后插入到右上角。
package com.changlu.demos;
import com.changlu.Main;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import java.io.File;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @Description: Apache PDFBox案例:將圖片縮小25%后插入到右上角。
* @Author: changlu
* @Date: 1:38 PM
*/
public class Demo5 {
public static void main(String[] args) throws Exception{
//讀取resources目錄下input.pdf文件
InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
PDDocument pdDocument = PDDocument.load(is);
//自定義字體 C:\Users\93997\Desktop\watermark tools\watermarkTools\target\classes\ttfs
//URLDecoder.decode() 方法來解碼 URL 編碼的路徑,將 %20 轉(zhuǎn)換回空格
String fontFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "ttfs" + File.separator + "Alibaba_PuHuiTi_2.0_65_Medium_65_Medium.ttf").getFile(), "UTF-8");
PDType0Font font = PDType0Font.load(pdDocument, new File(fontFile));
//遍歷原先的pdf文檔
for (PDPage page : pdDocument.getPages()) {
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
//添加圖片水印
//創(chuàng)建一個(gè)水印內(nèi)容流
PDPageContentStream imageContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
// 創(chuàng)建圖像對(duì)象
// PDImageXObject image = PDImageXObject.createFromFile("C:\\Users\\93997\\Desktop\\watermark tools\\watermarkTools\\src\\main\\resources\\images\\ConsultationGroupQRCode.jpg", pdDocument);
String pictureFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "images" + File.separator + "ConsultationGroupQRCode.jpg").getFile(), "UTF-8");
PDImageXObject image = PDImageXObject.createFromFile(pictureFile, pdDocument);
// 計(jì)算圖像的寬度和高度(縮小比例為0.3)
float imageWidth = (float) (image.getWidth() * 0.25);
float imageHeight = (float) (image.getHeight() * 0.25);
//具體圖片位置
float imageX = pageWidth - imageWidth - 10;
float imageY = pageHeight - imageHeight - 10;
// 在指定位置繪制圖像
imageContentStream.drawImage(image, imageX, imageY, imageWidth, imageHeight);
imageContentStream.close();
}
//目標(biāo)目錄 Thread.currentThread().getContextClassLoader().getResource("").getPath() 當(dāng)前工程目錄路徑
String targetPDFPath = "F:\\00核心知識(shí)、成果、視頻產(chǎn)出區(qū)\\技術(shù)視頻\\2024.2.15 自制默默學(xué)打水印工具 watermark tools\\watermarkTools\\src\\main\\resources\\output.pdf";
File outputFile = new File(targetPDFPath);
// 若是文件存在先進(jìn)行刪除
Files.deleteIfExists(Paths.get(outputFile.toURI()));
// 保存修改后的文檔
pdDocument.save(outputFile);
System.out.println("轉(zhuǎn)換任務(wù):" + targetPDFPath + " 成功!");
// 關(guān)閉文檔
pdDocument.close(); // 關(guān)閉文檔
}
}
效果:
參考文章
[1]. 使用 Apache PDFBox 操作PDF文件
[2]. Java使用pdfbox將已有的pdf添加頁眉
[3]. 基于pdfbox實(shí)現(xiàn)的pdf添加文字水印工具
資料獲取
大家點(diǎn)贊、收藏、關(guān)注、評(píng)論啦~
精彩專欄推薦訂閱:在下方專欄????文章來源:http://www.zghlxwxcb.cn/news/detail-830514.html
- 長(zhǎng)路-文章目錄匯總(算法、后端Java、前端、運(yùn)維技術(shù)導(dǎo)航):博主所有博客導(dǎo)航索引匯總
- 開源項(xiàng)目Studio-Vue—校園工作室管理系統(tǒng)(含前后臺(tái),SpringBoot+Vue):博主個(gè)人獨(dú)立項(xiàng)目,包含詳細(xì)部署上線視頻,已開源
- 學(xué)習(xí)與生活-專欄:可以了解博主的學(xué)習(xí)歷程
- 算法專欄:算法收錄
更多博客與資料可查看????獲取聯(lián)系方式????,??文末獲取開發(fā)資源及更多資源博客獲取??文章來源地址http://www.zghlxwxcb.cn/news/detail-830514.html
到了這里,關(guān)于開源PDF工具 Apache PDFBox 認(rèn)識(shí)及使用(知識(shí)點(diǎn)+案例)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!