依赖引入
...
dependencies {
...
implementation 'com.itextpdf:itextpdf:5.5.13.3'
implementation 'com.itextpdf:itext-asian:5.2.0'
...
}
...
代码展示
...
reader = new PdfReader(inputFile);
stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
//获取reader的原信息数据,这里拿到的是一个map,大家可以自己打印下map里的数据看看
HashMap<String, String> meta = reader.getInfo();
//这里是重置了PDF文件的Title,因为PPT转PDF的文件可能会出现标题和文件名不一致的情况。当然,我们也可以更改其他的元信息
meta.put("Title",file.getName());
//使修改后的元信息生效
stamper.setMoreInfo(meta);
...
以下代码是完整的demo代码,大家可以复制下来在本地运行,但记得修改输入文件和输出文件的名称
package org.example;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
public class PdfUtils {
public static void main(String[] args) throws Exception {
//需要添加水印的文件
String inputFile = "C:\\Users\\zxiong\\Downloads\\车载电器组2303008_82_206车型娱乐显示屏黑屏或重启.pdf";
//添加完水印的文件存放路径
String outputFile = "C:\\Users\\zxiong\\Downloads\\2.pdf";
//需要添加的水印文字
String waterMarkName = "添加水印";
//水印字体透明度
float opacity = 0.3f;
//水印字体大小
int fontsize = 40;
//水印倾斜角度(0-360)
int angle = 30;
//数值越大每页竖向水印越少
int heightDensity = 50;
//数值越大每页横向水印越少
int widthDensity = 10;
PdfUtils.addWaterMark(inputFile, outputFile, waterMarkName, opacity, fontsize, angle, heightDensity, widthDensity,false);
}
/**
* pdf添加水印
* @param inputFile 需要添加水印的文件
* @param outputFile 添加完水印的文件存放路径
* @param waterMarkName 需要添加的水印文字
* @param opacity 水印字体透明度
* @param fontsize 水印字体大小
* @param angle 水印倾斜角度(0-360)
* @param heightDensity 数值越大每页竖向水印越少
* @param widthDensity 数值越大每页横向水印越少
* @param cover 是否覆盖
* @return
*/
public static boolean addWaterMark(String inputFile, String outputFile, String waterMarkName,
float opacity, int fontsize, int angle, int heightDensity, int widthDensity,boolean cover) throws IOException {
if (!cover){
File file=new File(outputFile);
if (!file.exists()){
file.createNewFile();
}
}
File file=new File(inputFile);
if (!file.exists()){
return false;
}
PdfReader reader = null;
PdfStamper stamper = null;
try {
int interval = -5;
reader = new PdfReader(inputFile);
stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
HashMap<String, String> meta = reader.getInfo();
meta.put("Title",file.getName());
stamper.setMoreInfo(meta);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
//这里是透明度设置
gs.setFillOpacity(opacity);
//这里是条纹不透明度
gs.setStrokeOpacity(0.2f);
int total = reader.getNumberOfPages() + 1;
System.out.println("Pdf页数:" + reader.getNumberOfPages());
JLabel label = new JLabel();
FontMetrics metrics;
int textH = 0;
int textW = 0;
label.setText(waterMarkName);
metrics = label.getFontMetrics(label.getFont());
//字符串的高, 只和字体有关
textH = metrics.getHeight();
//字符串的宽
textW = metrics.stringWidth(label.getText());
PdfContentByte under;
//循环PDF,每页添加水印
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
under = stamper.getOverContent(i); //在内容上方添加水印
//under = stamper.getUnderContent(i); //在内容下方添加水印
under.saveState();
under.setGState(gs);
under.beginText();
//under.setColorFill(BaseColor.PINK); //添加文字颜色 不能动态改变 放弃使用
under.setFontAndSize(base, fontsize); //这里是水印字体大小
for (int height = textH; height < pageRect.getHeight() * 2; height = height + textH * heightDensity) {
for (int width = textW; width < pageRect.getWidth() * 1.5 + textW; width = width + textW * widthDensity) {
// rotation:倾斜角度
under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, angle);
}
}
//添加水印文字
under.endText();
}
System.out.println("添加水印成功!");
return true;
} catch (IOException e) {
System.out.println("添加水印失败!错误信息为: " + e);
e.printStackTrace();
return false;
} catch (DocumentException e) {
System.out.println("添加水印失败!错误信息为: " + e);
e.printStackTrace();
return false;
} finally {
//关闭流
if (stamper != null) {
try {
stamper.flush();
stamper.close();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
reader.close();
}
}
}
}
结语
1.重点部分就是先获取原文件的元信息,然后修改元信息。