在项目开中,我们经常需要为pdf文件添加水印,pdfbox和itextpdf网上只有对普通PDF添加水印的方法。
而Spire.Pdf则可直接对纯图PDF添加图片水印。
但是免费版只支持操作10页PDF,操作10页以上PDF时会受到限制。对此我们可以将PDF拆分成多个10页的PDF添加水印再合并。
Demo展示:
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.PdfPageSize;
import com.spire.pdf.graphics.PdfImage;
import com.spire.pdf.graphics.PdfMargins;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import java.awt.geom.Point2D;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class PdfTest {
/**
* 在pdf中插入图片(水印)
*/
public static void imageWatermark(String inputPath, String outputPath,String images){
try{
// 创建PdfDocument对象
PdfDocument originalDoc = new PdfDocument();
// 加载PDF文件
originalDoc.loadFromFile(inputPath);
// 设置页边距为左右0、上下0
PdfMargins margins = new PdfMargins(0,0);
// 调整画布,设置内容也根据页面的大小进行缩放
double wScale = (PdfPageSize.A4.getWidth() - 10) / PdfPageSize.A4.getWidth();
double hScale = (PdfPageSize.A4.getHeight() - 10) / PdfPageSize.A4.getHeight();
// 定义文件名存储List
List<String> inputPaths = new ArrayList<>();
// 获取原来PDF的总页数
int pageCount = originalDoc.getPages().getCount();
if(pageCount > 0){
// 判断需要生成几个PDF文件
int n = (int)Math.ceil((double)pageCount/10);
int x = 0;
// 循环生成PDF文件
for (int s = 1; s <= n; s++) {
//创建一个新的PdfDocument实例
PdfDocument newDoc = new PdfDocument();
//遍历所有PDF页面
for (int i = 0; i < 10; i++) {
if(x < pageCount){
PdfPageBase page = originalDoc.getPages().get(x);
x++;
//设置page大小为A4 如果page大小不是A4等标准页面为page添加水印会无效
PdfPageBase newPage = newDoc.getPages().add(PdfPageSize.A4,margins);
//调整画布,设置内容也根据页面的大小进行缩放
newPage.getCanvas().translateTransform(wScale, hScale);
//复制原文档的内容到新文档
newPage.getCanvas().drawTemplate(page.createTemplate(), new Point2D.Float());
}
}
//保存PDF
newDoc.saveToFile("D:\\test2\\tmp\\" + s + ".pdf");
// 关闭
newDoc.dispose();
newDoc.close();
// 保存文件存放路径
inputPaths.add("D:\\test2\\tmp\\" + s + ".pdf");
}
}
// 关闭
originalDoc.dispose();
originalDoc.close();
// 执行添加图片水印,合并PDF
int x = 1;
List<String> outputPaths = new ArrayList<>();
// 为拆分的PDF添加水印
for(String filePath : inputPaths){
// 添加水印后的PDF保持路径
String outputPath2 = "D:\\test2\\tmp\\22233333" + x + ".pdf";
outputPaths.add(outputPath2);
x ++;
FileInputStream fis = new FileInputStream(filePath);
//创建文档
PdfDocument pdf = new PdfDocument(fis);
//遍历所有PDF 页面
for (int i = 0; i < pdf.getPages().getCount(); i++) {
//添加一页
PdfPageBase page = pdf.getPages().get(i);
//加载图片,并获取图片高宽
PdfImage image = PdfImage.fromFile(images);
int width = image.getWidth()/2;
int height = image.getHeight()/2;
//绘制图片到PDF
page.getCanvas().drawImage(image,50,50,width, height);
}
//保存添加水印后的PDF
pdf.saveToFile(outputPath2);
pdf.dispose();
pdf.close();
// 关闭
fis.close();
}
// 合并添加好水印的PDF
PDFMergerUtility mergePdf = new PDFMergerUtility();
for (String outputPath3 : outputPaths) {
File f = new File(outputPath3);
if(f.exists() && f.isFile()){
// 循环添加要合并的pdf
mergePdf.addSource(f);
}
}
// 设置合并生成pdf文件名称
mergePdf.setDestinationFileName(outputPath);
// 执行合并pdf
mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
// 删除所有临时文件
File files = new File("D:\\test2\\tmp");
//判断是否为文件夹
if(files.exists() && files.isDirectory()){
//获取该文件夹下的子文件夹
File[] files2 = files.listFiles();
//循环子文件夹重复调用delete方法
for (int i = 0; i < files2.length; i++) {
files2[i].delete();
}
files.delete();
}
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String args[]) throws IOException {
PdfTest.imageWatermark("D:\\test2\\22222656.pdf", "D:\\test2\\333333.pdf", "D:\\test2\\11.jpg");
}
}
添加水印PDF前后对比
添加前
添加后