SpringBoot 实现 PDF 添加水印有哪些方案?


820543ad605989fa6c90322ee8c5e3f3.jpeg

简介

PDF(Portable Document Format,便携式文档格式)是一种流行的文件格式,它可以在多个操作系统和应用程序中进行查看和打印。在某些情况下,我们需要对 PDF 文件添加水印,以使其更具有辨识度或者保护其版权。本文将介绍如何使用 Spring Boot 来实现 PDF 添加水印的方式。

方式一:使用 Apache PDFBox 库

PDFBox 是一个流行的、免费的、用 Java 编写的库,它可以用来创建、修改和提取 PDF 内容。PDFBox 提供了许多 API,包括添加文本水印的功能。

添加 PDFBox 依赖

首先,在 pom.xml 文件中添加 PDFBox 的依赖:

<dependency>
&nbsp;&nbsp;&nbsp;&nbsp;<groupId>org.apache.pdfbox</groupId>
&nbsp;&nbsp;&nbsp;&nbsp;<artifactId>pdfbox</artifactId>
&nbsp;&nbsp;&nbsp;&nbsp;<version>2.0.24</version>
</dependency>

添加水印

在添加水印之前,需要读取原始 PDF 文件:

PDDocument&nbsp;document&nbsp;=&nbsp;PDDocument.load(new&nbsp;File( "original.pdf"));

然后,遍历 PDF 中的所有页面,并使用&nbsp;PDPageContentStream&nbsp;添加水印:

//&nbsp;遍历&nbsp;PDF&nbsp;中的所有页面
for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;document.getNumberOfPages();&nbsp;i++)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;PDPage&nbsp;page&nbsp;=&nbsp;document.getPage(i);
&nbsp;&nbsp;&nbsp;&nbsp;PDPageContentStream&nbsp;contentStream&nbsp;=&nbsp;new&nbsp;PDPageContentStream(document,&nbsp;page,&nbsp;PDPageContentStream.AppendMode.APPEND,&nbsp; true,&nbsp; true);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置字体和字号
&nbsp;&nbsp;&nbsp;&nbsp;contentStream.setFont(PDType1Font.HELVETICA_BOLD,&nbsp;36);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置透明度
&nbsp;&nbsp;&nbsp;&nbsp;contentStream.setNonStrokingColor(200,&nbsp;200,&nbsp;200);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;添加文本水印
&nbsp;&nbsp;&nbsp;&nbsp;contentStream.beginText();
&nbsp;&nbsp;&nbsp;&nbsp;contentStream.newLineAtOffset(100,&nbsp;100);&nbsp;//&nbsp;设置水印位置
&nbsp;&nbsp;&nbsp;&nbsp;contentStream.showText( "Watermark");&nbsp;//&nbsp;设置水印内容
&nbsp;&nbsp;&nbsp;&nbsp;contentStream.endText();

&nbsp;&nbsp;&nbsp;&nbsp;contentStream.close();
}

最后,需要保存修改后的 PDF 文件:

document.save(new&nbsp;File( "output.pdf"));
document.close();

完整代码

下面是使用 PDFBox 来实现 PDF 添加水印的完整代码:

import&nbsp;org.apache.pdfbox.pdmodel.PDDocument;
import&nbsp;org.apache.pdfbox.pdmodel.PDPage;
import&nbsp;org.apache.pdfbox.pdmodel.PDPageContentStream;
import&nbsp;org.apache.pdfbox.pdmodel.font.PDType1Font;

import&nbsp;java.io.File;
import&nbsp;java.io.IOException;

public&nbsp;class&nbsp;PdfBoxWatermark&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;IOException&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;读取原始&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PDDocument&nbsp;document&nbsp;=&nbsp;PDDocument.load(new&nbsp;File( "original.pdf"));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;遍历&nbsp;PDF&nbsp;中的所有页面
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;document.getNumberOfPages();&nbsp;i++)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PDPage&nbsp;page&nbsp;=&nbsp;document.getPage(i);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PDPageContentStream&nbsp;contentStream&nbsp;=&nbsp;new&nbsp;PDPageContentStream(document,&nbsp;page,&nbsp;PDPageContentStream.AppendMode.APPEND,&nbsp; true,&nbsp; true);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置字体和字号
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentStream.setFont(PDType1Font.HELVETICA_BOLD,&nbsp;36);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置透明度
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentStream.setNonStrokingColor(200,&nbsp;200,&nbsp;200);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;添加文本水印
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentStream.beginText();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentStream.newLineAtOffset(100,&nbsp;100);&nbsp;//&nbsp;设置水印位置
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentStream.showText( "Watermark");&nbsp;//&nbsp;设置水印内容
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentStream.endText();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentStream.close();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保存修改后的&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.save(new&nbsp;File( "output.pdf"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.close();
&nbsp;&nbsp;&nbsp;&nbsp;}
}

方式二:使用 iText 库

iText 是一款流行的 Java PDF 库,它可以用来创建、读取、修改和提取 PDF 内容。iText 提供了许多 API,包括添加文本水印的功能。

添加 iText 依赖

在&nbsp;pom.xml&nbsp;文件中添加 iText 的依赖:

<dependency>
&nbsp;&nbsp;&nbsp;&nbsp;<groupId>com.itextpdf</groupId>
&nbsp;&nbsp;&nbsp;&nbsp;<artifactId>itextpdf</artifactId>
&nbsp;&nbsp;&nbsp;&nbsp;<version>5.5.13</version>
</dependency>

添加水印

在添加水印之前,需要读取原始 PDF 文件:

PdfReader&nbsp;reader&nbsp;=&nbsp;new&nbsp;PdfReader( "original.pdf");
PdfStamper&nbsp;stamper&nbsp;=&nbsp;new&nbsp;PdfStamper(reader,&nbsp;new&nbsp;FileOutputStream( "output.pdf"));

然后,遍历 PDF 中的所有页面,并使用&nbsp;PdfContentByte&nbsp;添加水印:

//&nbsp;获取&nbsp;PDF&nbsp;中的页数
int&nbsp;pageCount&nbsp;=&nbsp;reader.getNumberOfPages();

//&nbsp;添加水印
for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;<=&nbsp;pageCount;&nbsp;i++)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;PdfContentByte&nbsp;contentByte&nbsp;=&nbsp;stamper.getUnderContent(i);&nbsp;//&nbsp;或者&nbsp;getOverContent()
&nbsp;&nbsp;&nbsp;&nbsp;contentByte.beginText();
&nbsp;&nbsp;&nbsp;&nbsp;contentByte.setFontAndSize(BaseFont.createFont(),&nbsp;36f);
&nbsp;&nbsp;&nbsp;&nbsp;contentByte.setColorFill(BaseColor.LIGHT_GRAY);
&nbsp;&nbsp;&nbsp;&nbsp;contentByte.showTextAligned(Element.ALIGN_CENTER,&nbsp; "Watermark",&nbsp;300,&nbsp;400,&nbsp;45);
&nbsp;&nbsp;&nbsp;&nbsp;contentByte.endText();
}

最后,需要保存修改后的 PDF 文件并关闭文件流:

stamper.close();
reader.close();

完整代码

下面是使用 iText 来实现 PDF 添加水印的完整代码:

import&nbsp;com.itextpdf.text.*;
import&nbsp;com.itextpdf.text.pdf.*;

import&nbsp;java.io.FileOutputStream;
import&nbsp;java.io.IOException;

public&nbsp;class&nbsp;ItextWatermark&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;IOException,&nbsp;DocumentException&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;读取原始&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PdfReader&nbsp;reader&nbsp;=&nbsp;new&nbsp;PdfReader( "original.pdf");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PdfStamper&nbsp;stamper&nbsp;=&nbsp;new&nbsp;PdfStamper(reader,&nbsp;new&nbsp;FileOutputStream( "output.pdf"));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;获取&nbsp;PDF&nbsp;中的页数
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;pageCount&nbsp;=&nbsp;reader.getNumberOfPages();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;添加水印
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;<=&nbsp;pageCount;&nbsp;i++)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PdfContentByte&nbsp;contentByte&nbsp;=&nbsp;stamper.getUnderContent(i);&nbsp;//&nbsp;或者&nbsp;getOverContent()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentByte.beginText();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentByte.setFontAndSize(BaseFont.createFont(),&nbsp;36f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentByte.setColorFill(BaseColor.LIGHT_GRAY);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentByte.showTextAligned(Element.ALIGN_CENTER,&nbsp; "Watermark",&nbsp;300,&nbsp;400,&nbsp;45);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentByte.endText();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保存修改后的&nbsp;PDF&nbsp;文件并关闭文件流
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stamper.close();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.close();
&nbsp;&nbsp;&nbsp;&nbsp;}
}

方式三:用 Ghostscript 命令行

Ghostscript 是一款流行的、免费的、开源的 PDF 处理程序,它可以用来创建、读取、修改和提取 PDF 内容。Ghostscript 中提供了命令行参数来添加水印。

Ghostscript

首先需要在本地安装 Ghostscript 程序。可通过以下链接下载安装包:

  • Windows[1]
  • macOS[2]
  • Linux[3]

添加水印

可以在终端中使用 Ghostscript 的命令行工具执行以下命令来实现:

gs&nbsp;-dBATCH&nbsp;-dNOPAUSE&nbsp;-sDEVICE=pdfwrite&nbsp;-sOutputFile=output.pdf&nbsp;-c&nbsp; "newpath&nbsp;/Helvetica-Bold&nbsp;findfont&nbsp;36&nbsp;scalefont&nbsp;setfont&nbsp;0.5&nbsp;setgray&nbsp;200&nbsp;200&nbsp;moveto&nbsp;(Watermark)&nbsp;show&nbsp;showpage"&nbsp;original.pdf

上述命令中,-sDEVICE=pdfwrite&nbsp;表示输出为 PDF 文件;-sOutputFile=output.pdf&nbsp;表示输出文件名为&nbsp;output.pdf;最后一个参数&nbsp;original.pdf&nbsp;则表示原始 PDF 文件的路径;中间的字符串则表示添加的水印内容。

注意事项

使用 Ghostscript 命令行添加水印时,会直接修改原始 PDF 文件,因此建议先备份原始文件。

方式四:Free Spire.PDF for Java

下面介绍一下使用 Free Spire.PDF for Java 实现 PDF 添加水印的方式。

Free Spire.PDF for Java 是一款免费的 Java PDF 库,它提供了一个简单易用的 API,用于创建、读取、修改和提取 PDF 内容。Free Spire.PDF for Java 也支持添加文本水印以及图片水印。

添加 Free Spire.PDF for Java 依赖

首先,在&nbsp;pom.xml&nbsp;文件中添加 Free Spire.PDF for Java 的依赖:

<dependency>
&nbsp;&nbsp;&nbsp;&nbsp;<groupId>e-iceblue</groupId>
&nbsp;&nbsp;&nbsp;&nbsp;<artifactId>free-spire-pdf-for-java</artifactId>
&nbsp;&nbsp;&nbsp;&nbsp;<version>1.9.6</version>
</dependency>

添加文本水印

在添加水印之前,需要读取原始 PDF 文件:

PdfDocument&nbsp;pdf&nbsp;=&nbsp;new&nbsp;PdfDocument();
pdf.loadFromFile( "original.pdf");

然后,遍历 PDF 中的所有页面,并使用&nbsp;PdfPageBase&nbsp;添加水印:

//&nbsp;遍历&nbsp;PDF&nbsp;中的所有页面
for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;pdf.getPages().getCount();&nbsp;i++)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;PdfPageBase&nbsp;page&nbsp;=&nbsp;pdf.getPages().get(i);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;添加文本水印
&nbsp;&nbsp;&nbsp;&nbsp;PdfWatermark&nbsp;watermark&nbsp;=&nbsp;new&nbsp;PdfWatermark( "Watermark");
&nbsp;&nbsp;&nbsp;&nbsp;watermark.setFont(new&nbsp;PdfFont(PdfFontFamily.Helvetica,&nbsp;36));
&nbsp;&nbsp;&nbsp;&nbsp;watermark.setOpacity(0.5f);
&nbsp;&nbsp;&nbsp;&nbsp;page.getWatermarks().add(watermark);
}

最后,需要保存修改后的 PDF 文件:

pdf.saveToFile( "output.pdf");
pdf.close();

添加图片水印

添加图片水印与添加文本水印类似,只需要将&nbsp;PdfWatermark&nbsp;的参数修改为图片路径即可。

//&nbsp;添加图片水印
PdfWatermark&nbsp;watermark&nbsp;=&nbsp;new&nbsp;PdfWatermark( "watermark.png");
watermark.setOpacity(0.5f);
page.getWatermarks().add(watermark);

完整代码

下面是使用 Free Spire.PDF for Java 来实现 PDF 添加水印的完整代码:

import&nbsp;com.spire.pdf.*;

public&nbsp;class&nbsp;FreeSpirePdfWatermark&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;读取原始&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PdfDocument&nbsp;pdf&nbsp;=&nbsp;new&nbsp;PdfDocument();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdf.loadFromFile( "original.pdf");

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;遍历&nbsp;PDF&nbsp;中的所有页面
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;pdf.getPages().getCount();&nbsp;i++)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PdfPageBase&nbsp;page&nbsp;=&nbsp;pdf.getPages().get(i);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;添加文本水印
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PdfWatermark&nbsp;watermark&nbsp;=&nbsp;new&nbsp;PdfWatermark( "Watermark");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watermark.setFont(new&nbsp;PdfFont(PdfFontFamily.Helvetica,&nbsp;36));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watermark.setOpacity(0.5f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;page.getWatermarks().add(watermark);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;添加图片水印
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;PdfWatermark&nbsp;watermark&nbsp;=&nbsp;new&nbsp;PdfWatermark( "watermark.png");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;watermark.setOpacity(0.5f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;page.getWatermarks().add(watermark);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保存修改后的&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdf.saveToFile( "output.pdf");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdf.close();
&nbsp;&nbsp;&nbsp;&nbsp;}
}

方式五:Aspose.PDF for Java

Aspose.PDF for Java 是一个强大的 PDF 处理库,提供了添加水印的功能。结合 Spring Boot 使用 Aspose.PDF for Java 库添加 PDF 水印的方式如下:

首先,在&nbsp;pom.xml&nbsp;文件中添加 Aspose.PDF for Java 的依赖:

<dependency>
&nbsp;&nbsp;&nbsp;&nbsp;<groupId>com.aspose</groupId>
&nbsp;&nbsp;&nbsp;&nbsp;<artifactId>aspose-pdf</artifactId>
&nbsp;&nbsp;&nbsp;&nbsp;<version>21.4</version>
</dependency>

在 Spring Boot 应用程序中调用 Aspose.PDF for Java 的 API 设置 PDF 水印。

添加文本水印

@PostMapping( "/addTextWatermark")
public&nbsp;ResponseEntity<byte[]>&nbsp;addTextWatermark(@RequestParam( "file")&nbsp;MultipartFile&nbsp;file)&nbsp;throws&nbsp;IOException&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;加载&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;pdfDocument&nbsp;=&nbsp;new&nbsp;Document(file.getInputStream());
&nbsp;&nbsp;&nbsp;&nbsp;TextStamp&nbsp;textStamp&nbsp;=&nbsp;new&nbsp;TextStamp( "Watermark");
&nbsp;&nbsp;&nbsp;&nbsp;textStamp.setWordWrap( true);
&nbsp;&nbsp;&nbsp;&nbsp;textStamp.setVerticalAlignment(VerticalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;textStamp.setHorizontalAlignment(HorizontalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.getPages().get_Item(1).addStamp(textStamp);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保存&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;ByteArrayOutputStream&nbsp;outputStream&nbsp;=&nbsp;new&nbsp;ByteArrayOutputStream();
&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.save(outputStream);
&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;ResponseEntity.ok()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.header(HttpHeaders.CONTENT_DISPOSITION,&nbsp; "attachment;&nbsp;filename=\"watermarked.pdf\"")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.contentType(MediaType.APPLICATION_PDF)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.body(outputStream.toByteArray());
}

添加图片水印

@PostMapping( "/addImageWatermark")
public&nbsp;ResponseEntity<byte[]>&nbsp;addImageWatermark(@RequestParam( "file")&nbsp;MultipartFile&nbsp;file)&nbsp;throws&nbsp;IOException&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;加载&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;pdfDocument&nbsp;=&nbsp;new&nbsp;Document(file.getInputStream());
&nbsp;&nbsp;&nbsp;&nbsp;ImageStamp&nbsp;imageStamp&nbsp;=&nbsp;new&nbsp;ImageStamp( "watermark.png");
&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setWidth(100);
&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setHeight(100);
&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setVerticalAlignment(VerticalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setHorizontalAlignment(HorizontalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.getPages().get_Item(1).addStamp(imageStamp);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保存&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;ByteArrayOutputStream&nbsp;outputStream&nbsp;=&nbsp;new&nbsp;ByteArrayOutputStream();
&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.save(outputStream);
&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;ResponseEntity.ok()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.header(HttpHeaders.CONTENT_DISPOSITION,&nbsp; "attachment;&nbsp;filename=\"watermarked.pdf\"")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.contentType(MediaType.APPLICATION_PDF)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.body(outputStream.toByteArray());
}

注意,以上代码中的文件名、宽度、高度等参数需要根据实际情况进行调整。

完整代码

完整的 Spring Boot 控制器类代码如下:

import&nbsp;com.aspose.pdf.*;
import&nbsp;org.springframework.http.HttpHeaders;
import&nbsp;org.springframework.http.MediaType;
import&nbsp;org.springframework.http.ResponseEntity;
import&nbsp;org.springframework.web.bind.annotation.*;
import&nbsp;org.springframework.web.multipart.MultipartFile;

import&nbsp;java.io.ByteArrayOutputStream;
import&nbsp;java.io.IOException;

@RestController
@RequestMapping( "/api/pdf")
public&nbsp;class&nbsp;PdfController&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;@PostMapping( "/addTextWatermark")
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ResponseEntity<byte[]>&nbsp;addTextWatermark(@RequestParam( "file")&nbsp;MultipartFile&nbsp;file)&nbsp;throws&nbsp;IOException&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;加载&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;pdfDocument&nbsp;=&nbsp;new&nbsp;Document(file.getInputStream());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TextStamp&nbsp;textStamp&nbsp;=&nbsp;new&nbsp;TextStamp( "Watermark");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textStamp.setWordWrap( true);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textStamp.setVerticalAlignment(VerticalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textStamp.setHorizontalAlignment(HorizontalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.getPages().get_Item(1).addStamp(textStamp);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保存&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteArrayOutputStream&nbsp;outputStream&nbsp;=&nbsp;new&nbsp;ByteArrayOutputStream();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.save(outputStream);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;ResponseEntity.ok()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.header(HttpHeaders.CONTENT_DISPOSITION,&nbsp; "attachment;&nbsp;filename=\"watermarked.pdf\"")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.contentType(MediaType.APPLICATION_PDF)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.body(outputStream.toByteArray());
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;@PostMapping( "/addImageWatermark")
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ResponseEntity<byte[]>&nbsp;addImageWatermark(@RequestParam( "file")&nbsp;MultipartFile&nbsp;file)&nbsp;throws&nbsp;IOException&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;加载&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;pdfDocument&nbsp;=&nbsp;new&nbsp;Document(file.getInputStream());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ImageStamp&nbsp;imageStamp&nbsp;=&nbsp;new&nbsp;ImageStamp( "watermark.png");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setWidth(100);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setHeight(100);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setVerticalAlignment(VerticalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imageStamp.setHorizontalAlignment(HorizontalAlignment.Center);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.getPages().get_Item(1).addStamp(imageStamp);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保存&nbsp;PDF&nbsp;文件
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteArrayOutputStream&nbsp;outputStream&nbsp;=&nbsp;new&nbsp;ByteArrayOutputStream();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pdfDocument.save(outputStream);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;ResponseEntity.ok()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.header(HttpHeaders.CONTENT_DISPOSITION,&nbsp; "attachment;&nbsp;filename=\"watermarked.pdf\"")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.contentType(MediaType.APPLICATION_PDF)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.body(outputStream.toByteArray());
&nbsp;&nbsp;&nbsp;&nbsp;}
}

这里使用了两个 RESTful API:/addTextWatermark&nbsp;和&nbsp;/addImageWatermark,分别用于添加文本水印和图片水印。在请求中通过&nbsp;file&nbsp;参数传递 PDF 文件。

下面介绍如何使用 Postman 来测试 Spring Boot 应用程序的 API。

  1. 下载并安装 Postman。
  2. 打开 Postman,选择 POST 请求方法。
  3. 在 URL 地址栏中输入&nbsp;http://localhost:8080/api/pdf/addTextWatermark。
  4. 在 Headers 标签页中设置 Content-Type 为 multipart/form-data。
  5. 在 Body 标签页中选择 form-data 类型,然后设置 key 为&nbsp;file,value 选择本地的 PDF 文件。
  6. 点击 Send 按钮发送请求,等待应答结果。

处理结果将会在响应的 Body 中返回,也可以选择浏览器下载或保存到本地磁盘。

以上就是使用 Aspose.PDF for Java 库结合 Spring Boot 添加 PDF 水印的方式。

结论

本文介绍了几种使用 Spring Boot 实现 PDF 添加水印的方式,分别是使用 Apache PDFBox 库、iText 库以及 Ghostscript 命令行等。选择哪种方式,可以根据项目需求和个人偏好来决定。无论采用哪种方式,都需要注意保护原始 PDF 文件,不要在不必要的情况下直接修改原始文件。欢迎点赞收藏,在你老板安排你干这时,希望你能够及时找到相关的Java工具库,实现这项功能。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/31501.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端项目工程化搭建

ESLint 在开发过程中&#xff0c;需要遵循一些规范&#xff0c;可以使用下面的工具来配置不同项目需要遵循的规范&#xff0c;来帮助我们检查错误、约束开发过程。 ESLint 配置 使用 Taro CLI 创建的项目&#xff0c;会自动生成 .eslintrc 文件。只需要在这个文件的 rules 配…

Android逆向解析加壳与脱壳技术

加壳 加壳是指在 APK 文件中插入额外的代码或数据&#xff0c;使得原始代码难以被分析和反编译。通常加壳是为了保护软件的知识产权或者防止逆向工程。下面是 Android 加壳的一般流程&#xff1a; 选择加壳工具&#xff1a;选择合适的加壳工具进行加壳&#xff0c;比如市面上…

K8S:二进制安装K8S(单台master)安装etcd和master

系列文章目录 文章目录 系列文章目录一、安装K8S1.系统初始化配置2.部署docker引擎3.部署etcd集群 二、1.2. 总结 一、安装K8S 1.系统初始化配置 注意&#xff1a;该操作在所有node节点上进行&#xff0c;为k8s集群提供适合的初始化部署环境 #所有节点执行 systemctl stop f…

POJ - 2287 Tian Ji -- The Horse Racing

题目来源 2287 -- Tian Ji -- The Horse Racing (poj.org) 题目描述 田忌赛马是中国历史上一个著名的故事。 这个故事发生在2300年前&#xff0c;田忌是齐国的一个大官&#xff0c;他喜欢和齐王以及其他公子赛马。 田忌和齐王都有三类马&#xff0c;分别是下等马&#xff0…

【Vue】学习笔记-创建Vue3.0工程

创建Vue3.0工程 使用vue-cli创建查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上安装或者升级你的vue/cli创建启动 使用vite创建创建工程进入工程目录安装依赖运行 使用vue-cli创建 官方文档&#xff1a;https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-…

BioXFinder生物数据库

BioXFinder是目前国内第一个也是国内唯一一个生物信息数据库&#xff0c;由享融智云公司精心研发&#xff0c;主要针对生物科研工作者的综合性生物数据检索及分析平台&#xff0c;汇集了核酸、蛋白、蛋白结构、代谢通路和信号通路信息&#xff0c;解决海外数据访问难、访问慢的…

【新星计划·2023】Linux是什么?它与Windows有什么区别?

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、Linux是什么&#xff1f; 二、Linux的应用领域 1、服务器领域 2、嵌入式领域 3、虚拟化 三、Linux的未来 1、云计算 2、大数…

玩转ChatGPT:回答审稿人问题

一、写在前面 前段时间一篇时间序列预测的文章返修&#xff0c;还挺幸运的&#xff0c;给了个小修。 不过问题也问得有点刁钻&#xff0c;应该是个行家。 想到手头有小Chat&#xff0c;打算使用TA来辅助我回答审稿人问题。 以下展示仅仅提供一个工作流和思路&#xff0c;具体…

高级SQL语句

目录 MySQL 高级(进阶) SQL 语句函数数学函数&#xff1a;聚合函数字符串函数&#xff1a; 连接查询inner join(内连接)&#xff1a;left join(左连接)&#xff1a;right join(右连接)&#xff1a; CREATE VIEW&#xff08;视图&#xff09;UNION&#xff08;联集&#xff09;C…

OpenAI ChatGPT 使用示例(程序员)

作为一个程序员&#xff0c;当知道ChatGPT出来之后或者GPT3出来的时候&#xff0c;我是有喜有忧&#xff0c;喜的是它可以帮我写代码&#xff0c;重构代码&#xff0c;写注释&#xff0c;写测试&#xff0c;&#xff0c;。哇&#xff0c;听起来好刺激&#xff0c;我可以从此以后…

探索安卓内容提供者:构建、访问和管理数据【复习】

文章目录 一 ContentProvider1.1 数据模型- **ContentProvider 使用基于数据库模型的简单表格来提供需要共享的数据**&#xff0c;在该表格中&#xff0c;每一表示一条记录&#xff0c;而每一列代表特定类型和含义的数据&#xff0c;并且其中每一条数据记录都包含一个名为“_ID…

数字图像处理 基于matlab、opencv计算图像的梯度方向和梯度幅值

一、图像的梯度 1、简述 图像可以被视为标量场(即二维函数)。 通过微分将标量场转换为矢量场。 梯度是一个向量,描述了在x或y方向上移动时,图像变化的速度。我们使用导数来回答这样的问题,图像梯度的大小告诉图像变化的速度,而梯度的方向告诉图像变化最…

【C++学习】C++入门 | 引用 | 引用的底层原理 | auto关键字 | 范围for(语法糖)

写在前面&#xff1a; 上一篇文章我介绍了缺省参数和函数重载&#xff0c; 探究了C为什么能够支持函数重载而C语言不能&#xff0c; 这里是传送门&#xff0c;有兴趣可以去看看&#xff1a;http://t.csdn.cn/29ycJ 这篇我们继续来学习C的基础知识。 目录 写在前面&#x…

图像金字塔

​ 图像金字塔是由一幅图像的多个不同分辨率的子图构成的图像集合。是通过一个图像不断的降低采样率产生的&#xff0c;最小的图像可能仅仅有一个像素点。下图是一个图像金子塔的示例。从图中可以看到&#xff0c;图像金字塔是一系列以金字塔形状排列的、自底向上分辨率逐渐降低…

【数字图像处理】3.对比度增强

目录 3.1 灰度直方图 3.2 线性变换 3.3 直方图正规化 3.4 伽马变换 3.5 全局直方图均衡化 3.6 CLAHE 对比度增强是图像增强的一种&#xff0c;它主要解决的是图像的灰度级范围较小造成的对比度较低的问题&#xff0c;目的是将图像的灰度级增强到指定范围&#xff0c;使得…

实战:用docker-compose容器化springboot项目

文章目录 前言技术积累docker-compose定义docker-compose文件参数docker-compose命令 实战演示1、创建挂载路径2、编写docker-compose.yml3、启动并管理容器 写在最后 前言 前面我们学习和实战了用dockerfile构建镜像&#xff0c;通过镜像可以任意在docker环境容器化部署项目。…

Opencv-C++笔记 (7) : opencv-文件操作XML和YMAL文件

文章目录 一、概述二、文件操作三、打开文件四、写入五、读写个人源码 一、概述 除了图像数据之外&#xff0c;有时程序中的尺寸较小的Mat类矩阵、字符串、数组等 数据也需要进行保存&#xff0c;这些数据通常保存成XML文件或者YAML文件。本小节中将介绍如何利用OpenCV 4中的函…

神经网络:卷积操作

当谈到计算机视觉中的网络模型结构时&#xff0c;卷积操作是其中一个关键的组成部分。卷积操作是一种基于局部区域的操作&#xff0c;它在计算机视觉中用于图像处理和特征提取。 卷积操作的原理如下&#xff1a; 给定一个输入图像和一个称为卷积核&#xff08;或滤波器&#x…

【ARIMA-SSA-LSTM】合差分自回归移动平均方法-麻雀优化-长短期记忆神经网络研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

前端Vue自定义数字输入框 带加减按钮的数字输入框组件

前端Vue自定义数字输入框 带加减按钮的数字输入框组件&#xff0c; 下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13163 效果图如下&#xff1a; # cc-numbox #### 使用方法 使用方法 <!-- title: 标题 isSetMax: 是否设置最…