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

news2024/11/15 2:14:41


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工具库,实现这项功能。



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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全国青少年软件编程(Scratch)等级考试二级考试真题2023年5月——持续更新.....

一、单选题(共25题,共50分) 1.运行下列哪段程序,可以让狗狗走到木屋门口?() A. B. C. D. 标准答案:C 2.下列哪个选项可以控制:按下左键扫帚向左旋转15度,按下右键扫帚向右旋转15度?() A. B. C.

LLM系列 | 09: 基于ChatGPT构建智能客服系统(query分类安全审核防注入)

简介 竹斋眠听雨&#xff0c;梦里长青苔。门寂山相对&#xff0c;身闲鸟不猜。小伙伴们好&#xff0c;我是卖热干面的小女孩。紧接前面几篇ChatGPT Prompt工程系列文章&#xff1a; 04:ChatGPT Prompt编写指南05:如何优化ChatGPT Prompt&#xff1f;06:ChatGPT Prompt实践&am…

如何安装MySQL数据库

目录 什么是MySQL数据库 第一步 安装依赖环境 第二步 创建MySQL相关进程用户 第三步 导入MySQL相关包 第四步 解包到指定目录下 第五步 切换到MySQL目录下编译安装 第六步 编译 第七步 更改指定文件的所有者和所属组 第八步 进入指定配置文件清空内容 第九步 配置指定…

软件测试复习题

一、填空题 软件从“出生”到“消亡”的过程称为___。早期的线性开发模型称为_______开发模型。引入风险分析的开发模型为_______开发模型。ISO 9126-1991标准提出的质量模型包括_______和________和________和______和_______和_______6大特性。按照缺陷的严重程度可以将缺陷…

如何做Web测试?测试者必知的常见测试点总结

目录 一、Web应用程序 二、功能测试 三、易用性测试(界面测试)整体界面测试 四、茶客性测试 五、安全性测试安全性测试要求: 六、性能测试 总结&#xff1a; 如何做Web测试?以下为大家比较全面地总结一下Web测试的票点 一、Web应用程序 应用程序有两种模式&#xff0c…

article-五轴机械臂正逆分析(标准法)VQ

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A2CiIK0R-1687071926271)(data:image/svgxml;utf8, )] 五轴机械臂正逆解仿真 标准的D-H参数法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PbUOp13D-1687071926272)(da…

设计模式-策略工厂

在介绍策略工厂的实现前&#xff0c;我们要先了解spring中beanFactory&#xff1a; BeanFactory 作为IOC服务的提供者&#xff0c;通过XmlBeanFactory来得到实例 生产Bean的工厂&#xff0c;采用延迟初始化策略&#xff08;只有在需要某个对象时&#xff0c;才进行初始化和依…

网络安全如何从零基础到精通?

在看这篇文章之前&#xff0c;有个问题想确认一下&#xff0c;你现在自学网络安全是出于兴趣原因&#xff0c;还是说之后准备走网络安全这个方向&#xff1f; 因为目的不同&#xff0c;学习的方式和深度也会不一样。 今天我就围绕职业发展这个方向来和你聊聊。 如果你真的想通过…

全国青少年软件编程(Scratch)等级考试一级考试真题2023年5月——持续更新.....

一、单选题(共25题&#xff0c;共50分) 1.看图找规律&#xff0c;请问下图红框中是&#xff1f;&#xff08; &#xff09; A. B. C. D. 标准答案&#xff1a;D 试题解析&#xff1a;通过观察每种图形有两个&#xff0c;所以选择D 2.用一根绳子绕树一圈余30厘米&#x…

小说推文洗稿的工作流程

牙叔教程 简单易懂 第一步 找到十万赞以上的爆款视频 自己刷呗, 多刷一些, 最好是那种粉丝几万到几十万的作者, 点赞数量在万赞以上的作品, 十万赞就更好啦 第二步 提取视频的文案 我们分享视频的时候, 有一个复制链接的按钮, 然后把链接复制到 逗哥配音 , 就可以把文案提取…

【QQ界面展示-通知的发布2 Objective-C语言】

一、我再把这个通知的发布与监听给大家复习一下, 1.我们发布和监听通知, 1)第一,需要一个对象,通知的发布者 2)第二,需要一个对象,通知的监听者 只有它俩,还不够,一个是通知的发布者、一个是通知的监听者, 只有它俩,根本不够, 你要想进行通知的发布、和监听,…

leetcode329. 矩阵中的最长递增路径(java)

矩阵中的最长递增路径 矩阵中的最长递增路径题目描述 暴力递归代码演示 递归 缓存代码演示 动态规划专题 矩阵中的最长递增路径 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/longest-increasing-path-in-a-matrix 题…

一文搞懂文件系统

目录 1.文件系统概述 2.文件命名 3.目录 3.1一级目录系统 3.2层次目录系统 4.文件系统的实现 4.1引导块 4.2超级块 4.3空闲空间块 4.3.1位图 4.3.2 使用链表进行管理 4.inode 5.记录文件所用磁盘块的方法 5.1连续分配 5.2链表分配 5.3inode 1.文件系统概述 文件系…

DC综合入门【待完善】

一、文件说明 工艺库 1、.db 格式&#xff1a;二进制工艺库文件&#xff1b;. lib 格式&#xff1a;可读工艺库文件&#xff08;包含 operating _ conditions ). 二、. synopsys _ dc . setup 搜索路径定义 1、set_search _ path [ list ./ home xxx(路径)] 2、多个地址可用&…

eclipse中创建一个maven父工程和几个模块(子工程)

示例&#xff1a;创建一个父工程和几个模块&#xff08;子工程&#xff09; 1&#xff09;、先创建一个父工程 注意&#xff1a;下面的Packaging选择pom&#xff1a; 点击Finish&#xff0c;父工程就创建好了&#xff1a; 2&#xff09;、再创建模块&#xff08;module&am…

软件测试用例三问,我的观点

背景 笔者最近换了新工作&#xff0c;可能是跟下属不熟悉的关系&#xff0c;昨天在会议上要求他们在用例中说清楚测试点。这句话引起了下属的一些情绪。我觉得这个问题有必要拿出来说一说&#xff0c;而且讨论这个问题的时候很容易从A变成B&#xff0c;这需要管理者警惕。 昨…

抖音如何查看自己上没上热门

抖音如何查看自己上没上热门 老铁&#xff0c;你的作品上热门了&#xff0c;你是不是还不知道呀&#xff1f; 如果说你还不知道怎么查看自己的作品上热门了&#xff0c;那么你一定要认真听我说。 首先呢&#xff0c;你的作品上热门播放量会比平时高几倍&#xff0c;几十倍&am…

@ConfigurationProperties 注解原理

前言 ConfigurationProperties注解是 SpringBoot 提供的一种更加便捷来处理配置文件中的属性值的方式&#xff0c;可以通过自动绑定和类型转换等机制&#xff0c;将指定前缀的属性集合自动绑定到一个Bean对象上。 加载原理 在 Springboot 启动流程加载配置的 prepareEnviron…

(2022,域邻近度)通过自适应感知核调制的 few-shot 图像生成

Few-shot Image Generation via Adaptation-Aware Kernel Modulation 公众号&#xff1a;EDPJ 目录 0. 摘要 1. 简介 2. 相关工作 3. 通过源-目标域接近度的视角重新审视 FSIG 3.1 源-目标域邻近度分析 3.2 临近假设松弛下的 FSIG 方法 4. 自适应感知核调制 5. 实证研…

js实现日历效果

使用js实现日历效果&#xff0c;主要用到了元素的创建以及添加 对应的方法是document.createElement()和document.appendChild() 主要实现思路&#xff1a; 用div布局把日历的页面框架搭建出来依次遍历上月&#xff0c;本月&#xff0c;下月的天数切换月份的时候首先清空所有日…