<dependencies>
<dependency>
<groupId>com.itextpdfgroupId>
<artifactId>itextpdfartifactId>
<version>5.5.13.3version>
dependency>
<dependency>
<groupId>org.bouncycastlegroupId>
<artifactId>bcprov-jdk15onartifactId>
<version>1.70version>
dependency>
<dependency>
<groupId>com.itextpdfgroupId>
<artifactId>itext-asianartifactId>
<version>5.2.0version>
dependency>
dependencies>
itextpdf是pdf操作的核心,bcprov-jdk15on用于pdf加密,itext-asian是亚洲字体
如果是读取本地pdf文件则可以用pdfStamper.setEncryption方法
// is为pdf文件输入流,os为要输出的文件流
PdfReader reader = new PdfReader(is);
PdfStamper stamper = new PdfStamper(reader, os);
// 设密码,禁止编辑
stamper.setEncryption("userPassword".getBytes(StandardCharsets.UTF_8), "ownerPassword".getBytes(StandardCharsets.UTF_8), PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY, PdfWriter.ENCRYPTION_AES_128);
如果是创建的pdf则可以用pdfWriter.setEncryption方法
// os为要输出的文件流
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, os);
writer.setEncryption("userPassword".getBytes(StandardCharsets.UTF_8), "ownerPassword".getBytes(StandardCharsets.UTF_8), PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY, PdfWriter.ENCRYPTION_AES_128);
setEncrption有4个参数:userPassword, ownerPassword, permissions, encryptionType
userPassword为用户密码,当用户打开时输入此密码将被赋予相应权限(见下面),该选项可以填null,表示无密码
ownerPassword为管理员密码,将获得文档全部权限,也可以填null
permissions为用户权限,多个权限以或(|)连接
encryptionType为加密方式,有4种:
PdfWriter.STANDARD_ENCRYPTION_40
PdfWriter.STANDARD_ENCRYPTION_128
PdfWriter.ENCRYPTION_AES_128
PdfWriter.ENCRYPTION_AES_256
从本地或服务器获取pdf文件输入流,添加水印并输出
// is为文件输入流,os为文件输出流,password为密码,watermark为水印字符串
PdfReader reader = new PdfReader(is);
PdfStamper stamper = new PdfStamper(reader, os);
// 设密码,禁止编辑
stamper.setEncryption(password == null ? null : password.getBytes(StandardCharsets.UTF_8), null, PdfWriter.ALLOW_COPY, PdfWriter.ENCRYPTION_AES_128);
// 水印字体
BaseFont base = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.EMBEDDED);
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.3f);
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
FontMetrics metrics;
int textH = 0;
int textW = 0;
label.setText(watermark);
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.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, 20);
under.setRGBColorFill(145,145,145);
// 页面填充水印
for (int height = textH; height < pageRect.getHeight(); height = height + textH * 10) {
for (int width = textW; width < pageRect.getWidth() + textW; width = width + textW * 3) {
under.showTextAligned( Element.ALIGN_LEFT,
watermark, width - textW,
height - textH, 30); // rotation是水印倾斜角度
}
}
under.endText();
under.restoreState();
}
stamper.close();
reader.close();
通过itext的Document类创建pdf,添加水印并输出。
设置PdfWriter的pageEvent事件,当新页面被创建时会触发事件的onStartPage方法,在这里添加水印即可。
// os为文件输出流,password为密码,watermark为水印字符串
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, os);
writer.setEncryption(password != null ? password.getBytes(StandardCharsets.UTF_8) : null, null, PdfWriter.ALLOW_COPY, PdfWriter.ENCRYPTION_AES_128);
BaseFont base = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.EMBEDDED);
Font font = new Font(base);
// 设置页面事件,在页面被创建的时候添加水印
writer.setPageEvent(new PdfPageEvent() {
@Override
public void onOpenDocument(PdfWriter pdfWriter, Document document) {}
@Override
public void onStartPage(PdfWriter pdfWriter, Document document) {
// 新的一页被创建后添加水印
Rectangle pageRect;
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.3f);
gs.setStrokeOpacity(0.4f);
JLabel label = new JLabel();
FontMetrics metrics;
label.setText(watermark);
metrics = label.getFontMetrics(label.getFont());
int textH = metrics.getHeight();
int textW = metrics.stringWidth(label.getText());
pageRect = pdfWriter.getPageSize();
PdfContentByte under = pdfWriter.getDirectContentUnder();
under.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, 20);
under.setRGBColorFill(145,145,145);
// 页面填充水印
for (int height = textH; height < pageRect.getHeight();
height = height + textH*10) {
for (int width = textW; width < pageRect.getWidth() + textW; width = width + textW*3) {
under.showTextAligned( Element.ALIGN_LEFT, watermark, width - textW, height - textH, 30); // rotation是水印倾斜角度
}
}
under.endText();
under.restoreState();
}
@Override
public void onEndPage(PdfWriter pdfWriter, Document document) { }
@Override
public void onCloseDocument(PdfWriter pdfWriter, Document document) { }
@Override
public void onParagraph(PdfWriter pdfWriter, Document document, float v) { }
@Override
public void onParagraphEnd(PdfWriter pdfWriter, Document document, float v) { }
@Override
public void onChapter(PdfWriter pdfWriter, Document document, float v, Paragraph paragraph) { }
@Override
public void onChapterEnd(PdfWriter pdfWriter, Document document, float v) { }
@Override
public void onSection(PdfWriter pdfWriter, Document document, float v, int i, Paragraph paragraph) { }
@Override
public void onSectionEnd(PdfWriter pdfWriter, Document document, float v) { }
@Override
public void onGenericTag(PdfWriter pdfWriter, Document document, Rectangle rectangle, String s) { }
});
document.open();
// 添加一些文本测试
for (int i = 0; i < 100; i++) {
Paragraph paragraph = new Paragraph("测试 test", font);
document.add(paragraph);
}
document.close();
os.flush();
os.close();
writer.close();