package util; import com.itextpdf.text.BaseColor; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.*; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; import java.io.*; /** * @Date 2022/3/4 14:19 * @Version 1.0 */ public class zspdfUtil { public static void main(String[] args) throws Exception { File pdf = new File("D:\\zhangshuai\\南京光大健康信息科技材料\\教育部学历证书电子注册备案表zs.pdf"); byte[] data = FileUtils.readFileToByteArray(pdf); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\testWM\\测试666.pdf"))); zspdfUtil.waterMark(bos, data, "江苏省卫生健康政务服务系统||https://jswjw.jsehealth.com/"); } //能进行换行使用,暂时可以 public static void waterMark( BufferedOutputStream bos, byte[] bytes, String waterMarkName) throws Exception { // 使用"||"将内容进行分割 | 需要用 \ 反斜杠做反义符 String[] waterMarkContents = waterMarkName.split("\\|\\|"); PdfReader reader = new PdfReader(bytes); PdfStamper stamper = new PdfStamper(reader, bos); //获取总页数+1 下面从1开始遍历 int total = reader.getNumberOfPages() + 1; BaseFont base = BaseFont.createFont("C:\\Windows\\Fonts\\simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); //这里的字体设置比较关键,这个设置支持中文的写法 // BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); int interval = 20; // 获取水印文字的最大高度和宽度 int textH = 0, textW = 0; for (int j = 0; j < waterMarkContents.length; j++) { JLabel label = new JLabel(); //因为j++了所以,先输出的是网址=https://jswjw.jsehealth.com/ label.setText(waterMarkContents[j]); if (waterMarkContents[j].length() % 2 == 0) { System.out.println("第一次名字分割为-------------+++++++++++"+waterMarkContents[j]); FontMetrics metrics = label.getFontMetrics(label.getFont()); if (textH < metrics.getHeight()) { textH = metrics.getHeight(); } if (textW < metrics.stringWidth(label.getText())) { textW = metrics.stringWidth(label.getText()); } // 设置水印透明度 PdfGState gs = new PdfGState(); gs.setFillOpacity(0.8f); gs.setStrokeOpacity(0.8f); Rectangle pageSizeWithRotation = null; PdfContentByte content = null; for (int i = 1; i < total; i++) { content = stamper.getOverContent(i); content.saveState(); content.setGState(gs); // 设置字体和字体大小 content.beginText(); content.setFontAndSize(base, 20); // 设置颜色 // content.setColorFill(BaseColor.RED); content.setColorFill(new BaseColor(0, 0, 0, 80)); // 获取每一页的高度、宽度 pageSizeWithRotation = reader.getPageSizeWithRotation(i); float pageHeight = pageSizeWithRotation.getHeight(); float pageWidth = pageSizeWithRotation.getWidth(); // 根据纸张大小多次添加, 水印文字成30度角倾斜 for (int height = interval + textH; height < pageHeight; height = height + textH * 16) { for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 2) { // 通过j==0 来输出 content.showTextAligned(Element.ALIGN_LEFT, waterMarkContents[j], width - textW, height - (textH + 10) , 30); } } content.endText(); } //这个时候不能关闭流,如果关闭了,下面的for循环就不能输出第二行数据了 // stamper.close(); // reader.close(); } } for (int j = 0; j < waterMarkContents.length; j++) { JLabel label = new JLabel(); //因为j++了所以,先输出的是网址=https://jswjw.jsehealth.com/ label.setText(waterMarkContents[j]); if (waterMarkContents[j].length()%2 != 0){ System.out.println("第二次名字分割为-------------+++++++++++"+waterMarkContents[j]); FontMetrics metrics = label.getFontMetrics(label.getFont()); if (textH < metrics.getHeight()) { textH = metrics.getHeight(); } if (textW < metrics.stringWidth(label.getText())) { textW = metrics.stringWidth(label.getText()); } // 设置水印透明度 PdfGState gs = new PdfGState(); gs.setFillOpacity(0.8f); gs.setStrokeOpacity(0.8f); Rectangle pageSizeWithRotation = null; PdfContentByte content = null; for (int i = 1; i < total; i++) { content = stamper.getOverContent(i); content.saveState(); content.setGState(gs); // 设置字体和字体大小 content.beginText(); content.setFontAndSize(base, 20); // 设置颜色 // content.setColorFill(BaseColor.RED); content.setColorFill(new BaseColor(0, 0, 0, 80)); // 获取每一页的高度、宽度 pageSizeWithRotation = reader.getPageSizeWithRotation(i); float pageHeight = pageSizeWithRotation.getHeight(); System.out.println("每页高度为:"+pageHeight); float pageWidth = pageSizeWithRotation.getWidth(); System.out.println("每页宽度为:"+pageWidth); // 根据纸张大小多次添加, 水印文字成30度角倾斜 for (int height = interval + textH; height < pageHeight; height = height + textH * 16) { for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 2) { //重点:根据y: 来设置每一行的高度 content.showTextAligned(Element.ALIGN_LEFT, waterMarkContents[j], width - textW, height - (textH + 120) , 30); } } content.endText(); } //最后关闭流关闭流 stamper.close(); reader.close(); } } } }
需要用到 下面 itextpdf jar包
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
最后样式