依赖
<dependency>
<groupId>com.lowagie.text</groupId>
<artifactId>com.springsource.com.lowagie.text</artifactId>
<version>2.0.8</version>
</dependency>
代码
/**
* 加水印
*
* @param pdfOutStream pdf的字节数组输出流
* @param outputStream 加完水印后的pdf输出流
* @param waterMark 水印内容
* @throws IOException
* @throws DocumentException
*/
private void addWaterMark(ByteArrayOutputStream pdfOutStream, OutputStream outputStream, String waterMark) throws IOException, DocumentException {
StringBuilder waterMarkLine = new StringBuilder(waterMark);
// 将 defaultWaterMarkNumInLine 条水印内容拼成一长串,这样在pdf中就会显示成连续的一行
int defaultWaterMarkNumInLine = 10;
for (int i = 0; i < defaultWaterMarkNumInLine; i++) {
waterMarkLine.append(" ").append(waterMark);
}
// 水印以平均距离展示 waterMarkNum 列在pdf上
int waterMarkNum = 3;
PdfReader pdfReader = new PdfReader(pdfOutStream.toByteArray());
BaseFont base = null;
try {
// 字体文件可以放在 项目/src/main/resources/ 下
// 注意 字体文件如果是.ttc的,路径中 “,1” 是必须的,不然会报错,如果是 .ttf 则不需要
base = BaseFont.createFont("font/simsun.ttc,1",
BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
} catch (DocumentException | IOException e) {
log.error("--> pdf加水印前获取字体失败", e);
throw new RuntimeException("pdf加水印前获取字体失败!");
}
PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream);
PdfContentByte content = null;
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
try {
if (base == null) {
return;
}
// 设置透明度为0.4
gs.setFillOpacity(0.4f);
gs.setStrokeOpacity(0.4f);
int toPage = pdfStamper.getReader().getNumberOfPages();
for (int i = 1; i <= toPage; i++) {
pageRect = pdfStamper.getReader().getPageSizeWithRotation(i);
// waterMarkNum 列水印,文档还会被 (waterMarkNum + 1) 等分
float xStep = pageRect.getWidth() / (waterMarkNum + 1);
float yStep = pageRect.getHeight() / (waterMarkNum + 1);
// 获得PDF最顶层
content = pdfStamper.getOverContent(i);
content.saveState();
// set Transparency
content.setGState(gs);
content.beginText();
content.setColorFill(new Color(224, 224, 224));
content.setFontAndSize(base, 40);
// 水印文字成45度角倾斜
for (int i1 = 0; i1 < waterMarkNum; i1++) {
// 计算水印X,Y坐标
float x = xStep * (i1 + 1);
float y = pageRect.getHeight() - (yStep * (i1 + 1));
content.showTextAligned(Element.ALIGN_CENTER, waterMarkLine.toString(), x, y, 45);
}
content.endText();
}
} catch (Exception e) {
log.error("--> pdf加水印失败", e);
throw new RuntimeException("pdf加水印失败!");
} finally {
pdfStamper.close();
}
}
关于字体文件
如果开发者是Windows系统,字体文件可以在 C:\Windows\Fonts
中找到,复制一份出来就好