Java基于iText7實(shí)現(xiàn)PDF添加通用文本水印的示例詳解
本文介紹如何使用 Java 在 PDF 文檔上添加通用的文字水印,示例基于 iText7,強(qiáng)調(diào)實(shí)現(xiàn)思路和關(guān)鍵 API,便于在任意項(xiàng)目中復(fù)用或擴(kuò)展。
1. 方案概覽
目標(biāo):在現(xiàn)有 PDF 文件的每一頁上添加居中、斜向、半透明的文字水印,例如「xx公司」。
適用場(chǎng)景:
- 預(yù)覽/下載前對(duì) PDF 加防泄露水?。?/li>
- 批量歸檔 PDF 時(shí)統(tǒng)一添加版權(quán)信息;
- 按用戶或租戶動(dòng)態(tài)生成個(gè)性化水?。ㄓ脩裘?、時(shí)間、IP 等)。
核心技術(shù)棧:
- Java 8+;
- iText7(
com.itextpdf:itext7-core); - 如需中文,建議引入中文字體依賴(如
font-asian或自備 TTF/OTF 字體)。
2. 基本依賴配置示例(Maven)
<dependencies>
<!-- iText7 主依賴(PDF 內(nèi)核) -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
<type>pom</type>
</dependency>
?
<!-- 可選:中文字體支持(也可以使用自帶 TTF 字體文件) -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>7.2.5</version>
</dependency>
</dependencies>
實(shí)際版本號(hào)可按項(xiàng)目統(tǒng)一依賴管理調(diào)整。
3. 實(shí)現(xiàn)思路
使用 PdfReader 讀取原始 PDF 輸入流(或文件)。
使用 PdfWriter 將處理結(jié)果寫入輸出流(內(nèi)存或新文件)。
構(gòu)造 PdfDocument 與高級(jí)布局對(duì)象 Document。
選擇合適的字體(特別是包含中文的字體)。
遍歷 PDF 的每一頁,計(jì)算頁面中心坐標(biāo),在對(duì)應(yīng)頁上繪制水印 Paragraph:
- 文本內(nèi)容:例如「xx公司」或某個(gè)動(dòng)態(tài)字符串;
- 字體、字號(hào)、顏色、透明度;
- 旋轉(zhuǎn)角度(如 45°)與對(duì)齊方式(居中)。
關(guān)閉文檔,輸出帶水印的 PDF。
4. 示例代碼:為每頁添加對(duì)角線文字水印
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;
?
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
?
public class PdfWatermarkUtil {
?
/**
* 為 PDF 每一頁添加斜向文字水印
*
* @param pdfInput 原始 PDF 輸入流
* @param watermark 水印文本(如 "xx公司")
* @return 帶水印 PDF 的字節(jié)數(shù)組
*/
public static byte[] addTextWatermark(InputStream pdfInput, String watermark) throws Exception {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
PdfReader reader = new PdfReader(pdfInput);
PdfWriter writer = new PdfWriter(out);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
Document document = new Document(pdfDoc);
?
PdfFont font = createFont();
?
int totalPages = pdfDoc.getNumberOfPages();
for (int i = 1; i <= totalPages; i++) {
Rectangle pageSize = pdfDoc.getPage(i).getPageSize();
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
float y = (pageSize.getTop() + pageSize.getBottom()) / 2;
?
Paragraph p = new Paragraph(watermark)
.setFont(font)
.setFontSize(60)
.setFontColor(new DeviceRgb(192, 192, 192))
.setOpacity(0.3f);
?
document.showTextAligned(
p,
x, y, i,
TextAlignment.CENTER,
VerticalAlignment.MIDDLE,
(float) Math.toRadians(45)
);
}
?
document.close();
pdfDoc.close();
return out.toByteArray();
}
}
?
/**
* 創(chuàng)建字體(示例:使用系統(tǒng)或自帶的中文字體)
*/
private static PdfFont createFont() throws Exception {
// 示例:使用內(nèi)置字體或自帶 TTF 文件
// 1)若有自定義字體:
// return PdfFontFactory.createFont("/path/to/simsun.ttf", PdfEncodings.IDENTITY_H, true);
// 2)簡化示例:使用內(nèi)置字體(不保證完整中文支持)
return PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", true);
}
}
5. 關(guān)鍵點(diǎn)與擴(kuò)展建議
字體選擇:對(duì)中文 PDF,盡量使用包含中文的 TTF/OTF 字體文件,并通過 PdfEncodings.IDENTITY_H 創(chuàng)建嵌入字體,避免亂碼。
透明度與字號(hào):可根據(jù)實(shí)際打印/預(yù)覽效果調(diào)整水印的字號(hào)和 setOpacity,在可見與不干擾閱讀之間取得平衡。
動(dòng)態(tài)水印:業(yè)務(wù)代碼中通常不會(huì)寫死「xx公司」,而是將水印文案作為參數(shù)傳入,例如「xx公司(機(jī)密)」或「用戶名+時(shí)間戳」。
性能考慮:對(duì)于非常大的 PDF(頁數(shù)很多),可以:
- 控制只對(duì)部分頁面加水印;
- 或在異步任務(wù)/批處理服務(wù)中執(zhí)行水印操作。
安全性:水印不能防止專業(yè)的 PDF 編輯/篡改,但對(duì)一般用戶的泄露行為有一定威懾與追責(zé)作用,可結(jié)合權(quán)限控制一同使用。
6. 總結(jié)
使用 iText7 給 PDF 添加文字水印的核心就是:讀取現(xiàn)有 PDF → 遍歷頁面 → 在每頁疊加一層半透明文本。上面的封裝方法只依賴 InputStream 與文案字符串,便于集成到上傳、下載或文件轉(zhuǎn)換鏈路中,實(shí)現(xiàn)統(tǒng)一的 PDF 水印策略。
以上就是Java基于iText7實(shí)現(xiàn)PDF添加通用文本水印的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Java iText7添加PDF水印的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在Spring Boot中使用Spark Streaming進(jìn)行實(shí)時(shí)數(shù)據(jù)處理和流式計(jì)算的步驟
這篇文章主要介紹了在Spring Boot中使用Spark Streaming進(jìn)行實(shí)時(shí)數(shù)據(jù)處理和流式計(jì)算,通過本文的介紹,我們了解了在Spring Boot中使用Spark Streaming進(jìn)行實(shí)時(shí)數(shù)據(jù)處理和流式計(jì)算的詳細(xì)步驟,需要的朋友可以參考下2024-03-03
避免Java內(nèi)存泄漏的10個(gè)黃金法則詳細(xì)指南
在Java開發(fā)領(lǐng)域,內(nèi)存泄漏是一個(gè)經(jīng)久不衰的話題,也是導(dǎo)致應(yīng)用程序性能下降、崩潰甚至系統(tǒng)癱瘓的常見原因,下面我們就來看看避免Java內(nèi)存泄漏的10個(gè)黃金法則吧2025-07-07
zuul轉(zhuǎn)發(fā)后服務(wù)取不到請(qǐng)求路徑的解決
這篇文章主要介紹了zuul轉(zhuǎn)發(fā)后服務(wù)取不到請(qǐng)求路徑的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java 單鏈表數(shù)據(jù)結(jié)構(gòu)的增刪改查教程
這篇文章主要介紹了Java 單鏈表數(shù)據(jù)結(jié)構(gòu)的增刪改查教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Java web Hibernate如何與數(shù)據(jù)庫鏈接
這篇文章主要介紹了Java web Hibernate如何與數(shù)據(jù)庫鏈接,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Spring Boot+Nginx實(shí)現(xiàn)大文件下載功能
相信很多小伙伴,在日常開放中都會(huì)遇到大文件下載的情況,大文件下載方式也有很多,比如非常流行的分片下載、斷點(diǎn)下載;當(dāng)然也可以結(jié)合Nginx來實(shí)現(xiàn)大文件下載,在中小項(xiàng)目非常適合使用,這篇文章主要介紹了Spring Boot結(jié)合Nginx實(shí)現(xiàn)大文件下載,需要的朋友可以參考下2024-05-05
java組件SmartUpload和FileUpload實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了java組件SmartUpload和FileUpload實(shí)現(xiàn)文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11

