简介
功能:Java实现PDF添加水印、添加页码、合并文档、拆分PDF、删除PDF
依赖:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.26</version>
</dependency>
代码
package xyz.zzrt.base.module.pdf.service;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
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.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;
import org.springframework.stereotype.Service;
/**
* PDF添加水印、添加页码、合并文档、拆分PDF、删除PDF
*/
@Service
public class PDFService {
/**
* PDF文件添加水印
*
* @param fileInputStream 源文件输入流
* @param fileOutputStream 目标文件输出流
* @param content 水印文本
*/
public static void waterMark(FileInputStream fileInputStream, FileOutputStream fileOutputStream, String content) throws IOException {
PDDocument document = PDDocument.load(fileInputStream);
// 遍历所有页面
for (PDPage page : document.getPages()) {
// 获取页面的宽和高
float width = page.getMediaBox().getWidth();
float height = page.getMediaBox().getHeight();
PDPageContentStream pageContentStream = new PDPageContentStream(document, page,
PDPageContentStream.AppendMode.APPEND, true, true);
// 设置水印的透明度
PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
extendedGraphicsState.setNonStrokingAlphaConstant(0.2F);
extendedGraphicsState.setAlphaSourceFlag(true);
pageContentStream.setGraphicsStateParameters(extendedGraphicsState);
// 设置水印的颜色(r,g,b)
pageContentStream.setNonStrokingColor(new Color(100, 100, 100));
pageContentStream.beginText();
// 设置字体
pageContentStream.setFont(PDType0Font.load(document, new File("src/main/resources/方正宋体简体.ttf")), 20);
// 根据纸张大小设置水印,30度倾斜
for (int h = 100; h < height; h += 100) {
for (int w = 20; w < width; w += 200) {
pageContentStream.setTextMatrix(Matrix.getRotateInstance(0.3, w, h));
pageContentStream.showText(content);
}
}
pageContentStream.endText();
pageContentStream.restoreGraphicsState();
pageContentStream.close();
}
document.save(fileOutputStream);
}
/**
* PDF添加页码
*/
public static void pagination(FileInputStream fileInputStream, FileOutputStream fileOutputStream)
throws IOException {
PDDocument document = PDDocument.load(fileInputStream);
// 总页数
int numberOfPages = document.getNumberOfPages();
// 遍历所有页面
for (int i = 0; i < numberOfPages; i++) {
PDPage page = document.getPage(i);
float width = page.getMediaBox().getWidth();
PDPageContentStream pageContentStream = new PDPageContentStream(document, page,
PDPageContentStream.AppendMode.APPEND, true, true);
pageContentStream.beginText();
pageContentStream.setFont(PDType0Font.load(document, new File("src/main/resources/方正宋体简体.ttf")), 12);
// 设置页码打印的位置
pageContentStream.newLineAtOffset(width - 100, 40);
pageContentStream.showText(String.format("第%d页/共%s页", i + 1, numberOfPages));
pageContentStream.endText();
pageContentStream.restoreGraphicsState();
pageContentStream.close();
}
document.save(fileOutputStream);
}
/**
* PDF文档合并
*/
public static void merge(FileOutputStream fileOutputStream, FileInputStream... fileInputStreams) throws IOException {
PDFMergerUtility mergerUtility = new PDFMergerUtility();
// 设置目标文件
mergerUtility.setDestinationStream(fileOutputStream);
for (FileInputStream fileInputStream : fileInputStreams) {
mergerUtility.addSource(fileInputStream);
}
mergerUtility.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
}
/**
* 拆分PDF
*
* @param fileInputStream 源文件输入流
* @param fileOutputStream 目标文件输出流
* @param pages 截取的页码
*/
public static void split(FileInputStream fileInputStream, FileOutputStream fileOutputStream, int[] pages)
throws IOException {
try (PDDocument originDocument = PDDocument.load(fileInputStream);
PDDocument targetDocument = new PDDocument();) {
Arrays.sort(pages);
for (int i = 0; i < pages.length; i++) {
targetDocument.addPage(originDocument.getPage(pages[i] - 1));
}
targetDocument.save(fileOutputStream);
}
}
/**
* 删除PDF指定页面
*/
public static void removePage(FileInputStream fileInputStream, FileOutputStream fileOutputStream, int[] pages)
throws IOException {
Arrays.sort(pages);
// 因为removePage之后文档的索引就会减少,所以使用这个辅助字段
int removedPageCount = 0;
try (PDDocument document = PDDocument.load(fileInputStream);) {
for (int i = 0; i < pages.length; i++) {
document.removePage(pages[i] - 1 - removedPageCount);
removedPageCount++;
}
document.save(fileOutputStream);
}
}
}