通過Java代碼實現PDF文件添加水印的功能,主要依賴iText庫(用于PDF操作)和OSS SDK(可選,用于文件上傳)。以下是實現的核心步驟:
首先添加依賴
<!-- 添加 PDF 水印 --><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>
添加PDF水印的核心方法
@SpringBootTest
public class FileWatermarkUploader {// OSS 配置信息:需根據你的賬號信息進行修改private static final String ENDPOINT = "your-endpoint";private static final String ACCESS_KEY_ID = "your-access-key";private static final String ACCESS_KEY_SECRET = "your-secret-key";private static final String BUCKET_NAME = "your-bucket-name";@Testpublic void T() throws Exception {uploadWithWatermark(new File("D:\\test.pdf"), "oss/path/output.pdf", "測試水印 - 保密 Confidential","D:/output/output.pdf");}/*** 上傳帶水印的文件至 OSS,并保存到本地指定路徑。** @param inputFile 原始 PDF 文件* @param objectName OSS 上保存的文件名* @param watermarkText 自定義水印文字* @param outputPath 本地保存路徑,如 "C:/output/watermarked.pdf"* @throws Exception 處理異常*/public void uploadWithWatermark(File inputFile, String objectName, String watermarkText, String outputPath)throws Exception {// 判斷是否是 PDF 文件if (!inputFile.getName().toLowerCase().endsWith(".pdf")) {throw new IllegalArgumentException("只支持 PDF 文件水印處理");}// 添加水印,返回本地水印文件File watermarkedFile = addPdfWatermark(inputFile, watermarkText);// 將臨時文件復制到指定輸出路徑copyFile(watermarkedFile, new File(outputPath));// 上傳到 OSS// uploadToOss(watermarkedFile, objectName);// 刪除臨時文件if (watermarkedFile.exists()) {watermarkedFile.delete();}}/*** 給 PDF 添加鋪滿整頁的文字水印** @param inputPdf 原始 PDF 文件* @param watermarkText 水印文字* @return 添加水印后的臨時文件* @throws IOException IO 異常* @throws DocumentException PDF 處理異常*/private File addPdfWatermark(File inputPdf, String watermarkText) throws IOException, DocumentException {File outputPdf = File.createTempFile("watermarked_", ".doc");PdfReader reader = new PdfReader(new FileInputStream(inputPdf));PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdf));int totalPages = reader.getNumberOfPages();BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);PdfGState gs = new PdfGState();gs.setFillOpacity(0.5f); // 半透明效果for (int i = 1; i <= totalPages; i++) {PdfContentByte canvas = stamper.getUnderContent(i);canvas.setGState(gs);canvas.setFontAndSize(font, 10);canvas.setColorFill(BaseColor.LIGHT_GRAY);float xSpacing = 150f; // 橫向間隔float ySpacing = 100f; // 縱向間隔for (float x = 0; x < 595; x += xSpacing) { // 頁面寬度 A4 約 595ptfor (float y = 0; y < 842; y += ySpacing) { // 頁面高度 A4 約 842ptcanvas.beginText();canvas.showTextAligned(Element.ALIGN_CENTER, watermarkText, x, y, 45);canvas.endText();}}}stamper.close();reader.close();return outputPdf;}/*** 上傳文件至 OSS** @param file 文件對象* @param objectName OSS 保存的文件名* @throws FileNotFoundException 文件找不到異常*/private void uploadToOss(File file, String objectName) throws FileNotFoundException {OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);ossClient.putObject(BUCKET_NAME, objectName, new FileInputStream(file));ossClient.shutdown();}/*** 將文件從源路徑復制到目標路徑** @param source 原始文件* @param destination 目標文件* @throws IOException IO 異常*/private void copyFile(File source, File destination) throws IOException {try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(destination)) {byte[] buffer = new byte[1024];int length;while ((length = in.read(buffer)) > 0) {out.write(buffer, 0, length);}}}
}
關鍵點說明
- iText依賴:需在項目中引入iText庫(如com.itextpdf:itextpdf:5.2.0)。
- 水印樣式:通過PdfGState設置透明度,通過BaseFont設置字體,通過showTextAligned控制水印位置和旋轉角度。
- 水印密度:通過xSpacing和ySpacing調整水印排列密度。
- 臨時文件處理:生成水印文件后建議刪除臨時文件,避免存儲浪費。