在word生成pdf后,或者上传pdf文件,用户希望给pdf文档添加水印信息,具体代码如下
一. 首先pom中需要引入
<!-- PDF水印-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- 中文字体 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
核心代码如下,写在某个 service 下面
public void signPdf(InputStream is, Supplier<OutputStream> os, List<WaterMarkInfoRequest> signList) {
PdfStamper stamper = null;
PdfReader reader = null;
try {
reader = new PdfReader(is);
stamper = new PdfStamper(reader, os.get());
for (WaterMarkInfoRequest s : signList) {
TextWaterMarkRequest textWaterMark = s.getTextWaterMark();
if (textWaterMark != null) {
//添加文字
BaseFont baseFont;
try {
baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
} catch (DocumentException | IOException e) {
log.info("pdf签名获取字体信息异常:{}", e.getMessage(), e);
throw new BusinessException(IO_ERROR.toErrorInfos("pdf签名获取字体信息异常"));
}
PdfContentByte content = stamper.getOverContent(textWaterMark.getPageNo());
PdfGState gState = new PdfGState();
//设置透明度
gState.setFillOpacity(textWaterMark.getAlpha());
content.setGState(gState);
content.beginText();
//设置字体
content.setFontAndSize(baseFont, textWaterMark.getFontSize());
//设置颜色
content.setColorFill(new BaseColor(0xFF << 24 | Integer.parseInt(textWaterMark.getFontColor(), 16)));
//设置水印内容和位置
content.showTextAligned(Element.ALIGN_MIDDLE, textWaterMark.getText(), textWaterMark.getIntervalVertical(), textWaterMark.getIntervalHorizontal(), 0f);
content.endText();
}
ImageWaterMarkRequest imageWaterMark = s.getImageWaterMark();
if (imageWaterMark != null) {
//添加图片
PdfContentByte content = stamper.getOverContent(imageWaterMark.getPageNo());
PdfGState gState = new PdfGState();
//设置透明度
gState.setFillOpacity(imageWaterMark.getAlpha());
//image
Image image = Image.getInstance(EncryptUtil.base64DecoderToBytes(imageWaterMark.getBase64Str()));
image.setAbsolutePosition(imageWaterMark.getPositionX(), imageWaterMark.getPositionY());
if (imageWaterMark.getScaleAbsoluteX() != null && imageWaterMark.getScaleAbsoluteY() != null) {
image.scaleToFit(imageWaterMark.getScaleAbsoluteX(), imageWaterMark.getScaleAbsoluteY());
} else if (imageWaterMark.getScalePercent() != null && imageWaterMark.getScalePercent() > 0) {
image.scalePercent(imageWaterMark.getScalePercent());
}
content.addImage(image);
content.stroke();
}
}
} catch (Exception e) {
e.printStackTrace();
log.info("添加签名失败:{}", e.getLocalizedMessage(), e);
WM_WRITE_ERR.throwException();
} finally {
if (null != stamper) {
try {
stamper.close();
} catch (Exception e) {
log.info("关闭失败:{}", e.getMessage(), e);
}
}
if (null != reader) {
reader.close();
}
}
}
用到的实体类
public class ImageWaterMarkRequest{
@ApiModelProperty(value = "需要添加的页码,默认所有页码都添加")
private Integer pageNo;
@ApiModelProperty(value = "水平位置 左下角坐标(0,0)")
private Integer positionX;
@ApiModelProperty(value = "垂直位置 左下角坐标(0,0)")
private Integer positionY;
@ApiModelProperty(value = "指定图像宽度 ")
private Integer scaleAbsoluteX;
@ApiModelProperty(value = "指定图像高度 ")
private Integer scaleAbsoluteY;
@ApiModelProperty(value = "缩放比例 与指定尺寸冲突 优先使用指定图像尺寸")
private Integer scalePercent;
@ApiModelProperty(value = "图片的二进制数据")
@NotNull
private String base64Str;
@ApiModelProperty(value = "透明度 0--1")
private Float alpha;
@ApiModelProperty(value = "透明度 0--1",hidden = true)
private Float opacity;
@ApiModelProperty(value = "是否水印打在最顶层 默认true")
private Boolean isTop;
}
public class WaterMarkInfoRequest {
@ApiModelProperty(value = "文字水印信息")
private TextWaterMarkRequest textWaterMark;
@ApiModelProperty(value = "图片水印信息")
private ImageWaterMarkRequest imageWaterMark;
}
方法测试
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
public class PdfWaterMarkServiceImplTest {
public static void main(String[] args) throws Exception {
InputStream is = Files.newInputStream(Paths.get("/Users/cong/Downloads/a.pdf"));
OutputStream outputStream = Files.newOutputStream(Paths.get("/Users/cong/Downloads/q-5.pdf"));
ArrayList<WaterMarkInfoRequest> requests = new ArrayList<>();
WaterMarkInfoRequest waterMarkInfo = addSign(1);
WaterMarkInfoRequest waterMarkInfo2 = addSign(1);
requests.add(waterMarkInfo);
requests.add(waterMarkInfo2);
//调用你自己服务的pdf水印方法
new PdfWaterMarkServiceImpl().signPdf(is, () -> outputStream, requests);
outputStream.close();
}
private static WaterMarkInfoRequest addSign(Integer pageNum) {
WaterMarkInfoRequest waterMarkInfo = new WaterMarkInfoRequest();
ImageWaterMarkRequest imageWaterMark = new ImageWaterMarkRequest();
imageWaterMark.setPageNo(pageNum);
imageWaterMark.setPositionY(200);
imageWaterMark.setPositionX(200);
imageWaterMark.setTop(true);
imageWaterMark.setAlpha(1.0f);
imageWaterMark.setBase64Str("图片base64");
waterMarkInfo.setImageWaterMark(imageWaterMark);
TextWaterMarkRequest textWaterMark = new TextWaterMarkRequest();
textWaterMark.setText("我是一个水印");
textWaterMark.setRotation(0);
textWaterMark.setAlpha(1.0f);
textWaterMark.setFontSize(24);
textWaterMark.setIntervalHorizontal(10);
textWaterMark.setIntervalVertical(10);
textWaterMark.setFontColor("800000");
textWaterMark.setTop(true);
textWaterMark.setPageNo(pageNum);
waterMarkInfo.setTextWaterMark(textWaterMark);
return waterMarkInfo;
}
}