2007word与PDF添加水印
因itext和spire.office 商业收费,在网上找了许多样例,最后找到了POI与PDFbox来为文档添加水印
一、POM文件引包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.3.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>WaterRemark</artifactId> <version>0.0.1-SNAPSHOT</version> <name>WaterRemark</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <!--<repositories> <repository> <id>com.e-iceblue</id> <url>http://repo.e-iceblue.cn/repository/maven-public/</url> </repository> </repositories>--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!--<dependency> <groupId>e-iceblue</groupId> <artifactId>spire.doc</artifactId> <version>3.5.5</version> </dependency>--> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <!--2003版本--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>4.1.2</version> </dependency> <!--PDF添加水印--> <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.20</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
二、word简单生成水印
package com.example.demo.office; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFHeader; import org.apache.poi.xwpf.usermodel.XWPFParagraph; public class WordWaterMark { public static void main(String[] args) { String mdocPath = "D:\\installApp\\Java\\tmp\\waterMark.docx"; String waterParh = "D:\\installApp\\Java\\tmp\\waterMark2.docx"; String wmText = "水印实验"; waterMark2007(mdocPath, waterParh, wmText); /* * String mdocPath1 = "D:\\installApp\\Java\\tmp\\doc1.doc"; String waterParh1 = * "D:\\installApp\\Java\\tmp\\waterDoc2.doc"; */ } public static void waterMark2007(String mdocPath,String waterParh, String wmText) { XWPFDocument xwpfDocument = null; FileOutputStream fileOutputStream = null; try { xwpfDocument = new XWPFDocument(new FileInputStream(mdocPath)); //获取所有存在的内容,包含页眉和页脚 XWPFHeaderFooterPolicy headerFooterPolicy = xwpfDocument.getHeaderFooterPolicy(); if(headerFooterPolicy==null) { headerFooterPolicy = xwpfDocument.createHeaderFooterPolicy(); } //创建水印 headerFooterPolicy.createWatermark(wmText); //获取默认的页眉 XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT); //段落 返回包含页眉页脚的段落 XWPFParagraph paragraphArray = header.getParagraphArray(0); System.out.println(paragraphArray.getCTP().getRArray(0)); System.out.println(paragraphArray.getCTP().getRArray(0).getPictArray(0)); org.apache.xmlbeans.XmlObject[] xmlobjects = paragraphArray.getCTP().getRArray(0).getPictArray(0).selectChildren( new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape")); if (xmlobjects.length > 0) { com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape)xmlobjects[0]; // set fill color //ctshape.setFillcolor("#d8d8d8"); //设置水印颜色 ctshape.setFillcolor("#CC00FF"); // set rotation //设置水印倾斜 ctshape.setStyle(ctshape.getStyle() + ";rotation:315"); } fileOutputStream = new FileOutputStream(waterParh); xwpfDocument.write(fileOutputStream); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { if(xwpfDocument!=null) { xwpfDocument.close(); } if(fileOutputStream!=null) { fileOutputStream.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // https://www.jianshu.com/p/911d504193cb }
三、PDF生成水印
package com.example.demo.pdf; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState; import org.apache.pdfbox.util.Matrix; import java.awt.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class PDFWaterMark { public static void main(String[] args) { String sourcePath = "D:\\杂项\\tmp.pdf"; String targetPath = "D:\\杂项\\tmpwater1.pdf"; String fontPath = "D:\\杂项\\msyh.ttf"; String waterStr = " 泰康 "; addWaterMark(sourcePath,targetPath,waterStr,fontPath);
//第二种生成PDF水印方法,tmp文件作为Pdf 水印添加测试文件.pdf的水印来生成带水印的PDF
String sourcePath = "/home/tmpPackage/Pdf 水印添加测试文件.pdf";
String waterMarkPath = "/home/tmpPackage/tmp.pdf";
addWaterMark2(sourcePath,waterMarkPath);
}
public static void addWaterMark2(String sourcePath,String waterMarkPath) { //加载pdf文件 try { PDDocument document = PDDocument.load(new File(sourcePath)); HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>(); for(int i=0; i<document.getNumberOfPages(); i++){ overlayGuide.put(i+1, waterMarkPath); //watermark.pdf is the document which is a one page PDF with your watermark image in it. //Notice here, you can skip pages from being watermarked. } Overlay overLay = new Overlay(); overLay.setInputPDF(document); overLay.setOverlayPosition(Overlay.Position.BACKGROUND); PDDocument finalDOc = overLay.overlay(overlayGuide); finalDOc.save(sourcePath); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
public static void addWaterMark(String sourcePath,String targetPath,String waterStr,String fontPath){ try { //加载pdf文件 PDDocument document = PDDocument.load(new File(sourcePath)); //解除安全 document.setAllSecurityToBeRemoved(true); //获取PDF所有页,遍历 for(PDPage page : document.getPages()){ //PDF内容流 //第一个参数要修改的文件,第二个修改的页面,第三个更改是追加还是覆盖,第四个是否压缩,第五个参数是否重置是第三位追加时true PDPageContentStream pdPageContentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true); //引入字体文件 解决中文汉字乱码问题 PDFont font = PDType0Font.load(document, new FileInputStream(fontPath), true); // PDFont font = PDType1Font.HELVETICA_OBLIQUE; //字体大小 float fontHeight = 20; // arbitrary for short text //整页只有一个水印 start //页面宽度 /*float width = page.getMediaBox().getWidth(); //页面高度 float height = page.getMediaBox().getHeight(); //水印宽度 float stringWidth = font.getStringWidth(waterStr) / 1000 * fontSize; //一脸懵的开平方根 float diagonalLength = (float) Math.sqrt(width * width + height * height); //正切,现象就是水印是斜的~-~ float angle = (float) Math.atan2(height, width); //x轴坐标 float x = (diagonalLength - stringWidth) / 2; // "horizontal" position in rotated world //y轴坐标 float y = -fontSize / 4; // 4 is a trial-and-error thing, this lowers the text a bit pdPageContentStream.transform(Matrix.getRotateInstance(angle, 0, 0));*/ //整页只有一个水印 end //创建图形拓展字典类 PDExtendedGraphicsState pdExtendedGraphicsState = new PDExtendedGraphicsState(); //透明度 pdExtendedGraphicsState.setNonStrokingAlphaConstant(0.3f); pdExtendedGraphicsState.setStrokingAlphaConstant(0.3f); pdExtendedGraphicsState.setAlphaSourceFlag(true); pdPageContentStream.setGraphicsStateParameters(pdExtendedGraphicsState); //水印颜色 pdPageContentStream.setNonStrokingColor(Color.GREEN); pdPageContentStream.setStrokingColor(Color.red); pdPageContentStream.beginText(); pdPageContentStream.setFont(font, fontHeight); //根据水印文字大小长度计算横向坐标需要渲染几次水印 float h = waterStr.length() * fontHeight; for (int i = 0; i <= 10; i++) { // 获取旋转实例 pdPageContentStream.setTextMatrix(Matrix.getRotateInstance(-150, i * 100, 0)); pdPageContentStream.showText(waterStr); for (int j = 0; j < 20; j++) { pdPageContentStream.setTextMatrix(Matrix.getRotateInstance(-150, i * 100, j * h)); pdPageContentStream.showText(waterStr); } } // pdPageContentStream.showText(waterStr); pdPageContentStream.endText(); pdPageContentStream.restoreGraphicsState(); pdPageContentStream.close(); } document.save(new File(targetPath)); document.close(); } catch (IOException e) { e.printStackTrace(); } } }
*有不足请指出,仅是学习过程中记录

浙公网安备 33010602011771号