一、使用Aspose
1、前言:
1)Aspose可能需要收费,在https://mvnrepository.com/上有可能下载不下来,所以配上Aspose.Pdf的jar包
链接:https://pan.baidu.com/s/1kqhgT1hUsNxCR1xE9hIUkA
提取码:1el6
2)如果想下载源文件可以进行下载
https://download.csdn.net/download/Romantic_321/20626543
https://download.csdn.net/download/Romantic_321/20626539
2、创建一个模型对象
package com.test.model; /** * @author * @Description * @date */ public class PdfAsposeModel { private Double xCoordinate; private Double yCoordinate; private Integer pageNum; private String content; public Double getxCoordinate() { return xCoordinate; } public void setxCoordinate(Double xCoordinate) { this.xCoordinate = xCoordinate; } public Double getyCoordinate() { return yCoordinate; } public void setyCoordinate(Double yCoordinate) { this.yCoordinate = yCoordinate; } public Integer getPageNum() { return pageNum; } public void setPageNum(Integer pageNum) { this.pageNum = pageNum; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public PdfAsposeModel(Double xCoordinate, Double yCoordinate, Integer pageNum, String content) { this.xCoordinate = xCoordinate; this.yCoordinate = yCoordinate; this.pageNum = pageNum; this.content = content; } }
3、demo测试
package com.test.asposeTest; import com.aspose.pdf.*; import com.test.model.PdfAsposeModel; import org.junit.Test; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * @author qiuzhenshuo * @Description pdf根据坐标合成 * @date 2021-07-28 */ public class AsposePdfTest2 { private static final String FONT = "SimSun"; private static final float FONTSIZE = 15; @Test public void asposeTest(){ List<PdfAsposeModel> list = new ArrayList<>(); list.add(new PdfAsposeModel(119d,707d,1,"阿里巴巴")); list.add(new PdfAsposeModel(119d,619d,1,"张三")); list.add(new PdfAsposeModel(119d,475d,1,"奥利给")); String filePath = "C:/Users/Dash/Desktop/劳动合同(标准版).pdf"; try { pdfSign2(filePath,list); } catch (IOException e) { e.printStackTrace(); } } public void pdfSign2(String pdfFilePath,List<PdfAsposeModel> list) throws IOException { //获取路径 int indexOf = pdfFilePath.lastIndexOf("/"); if(indexOf == -1){ indexOf = pdfFilePath.lastIndexOf("\\"); } int indexOf2 = pdfFilePath.lastIndexOf("."); String suffix = pdfFilePath.substring(indexOf2); String url = pdfFilePath.substring(0,indexOf+1); url = url + UUID.randomUUID().toString() + suffix; //复制一份文件,因为需要生成一份新的文件,下面方法是在源文件上进行操纵的 FileInputStream inputStream = null; FileOutputStream outputStream = null; try { inputStream = new FileInputStream(pdfFilePath); outputStream = new FileOutputStream(url); int hasRead =0; while((hasRead = inputStream.read()) != -1){ outputStream.write(hasRead); } } catch (IOException e) { e.printStackTrace(); }finally { inputStream.close(); outputStream.close(); } for (PdfAsposeModel model : list) { Double xCoordinate = model.getxCoordinate(); Double yCoordinate = model.getyCoordinate(); String content = model.getContent(); Integer pageNum = model.getPageNum(); if(xCoordinate == null || yCoordinate == null || content == null || "".equals(content) || pageNum == null || pageNum < 1){ continue; } //添加内容 Document document=new Document(url); if (document!=null) { Page page = document.getPages().get_Item(pageNum); if (page != null) { TextParagraph paragraph = new TextParagraph(); paragraph.getFormattingOptions().setWrapMode( TextFormattingOptions.WordWrapMode.ByWords); TextState textState = new TextState(); Font pdfFont = FontRepository.findFont(FONT, true); textState.setFont(pdfFont); textState.setFontSize(FONTSIZE); paragraph.appendLine(content, textState); Position position = new Position(xCoordinate, yCoordinate); paragraph.setPosition(position); TextBuilder textBuilder = new TextBuilder(page); textBuilder.appendParagraph(paragraph); } else { System.out.println("页面第:" + pageNum + "页不存在"); } document.save(); } } } }
二、使用Itext
1、前言
附:所使用到的依赖
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-pdfa</artifactId> <version>5.5.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-xtra</artifactId> <version>5.5.12</version> <exclusions> <exclusion> <groupId>org.apache.commons</groupId> <artifactId>commons-imaging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.12</version> </dependency>
2、创建模型
* itext大致和aspose一样,只不过aspose坐标是Double类型,而Itext是Float类型,所以在此基础上更改一下类型即可
3、测试demo
1)测试方法
@Test public void pdfTest() throws IOException, DocumentException { System.out.println("-------------开始时间:"+new Date()); List<PdfItextModel> list = new ArrayList<>(); list.add(new PdfItextModel(119f,707f,1,"阿里巴巴")); list.add(new PdfItextModel(119f,619f,1,"张三")); list.add(new PdfItextModel(119f,475f,1,"奥利给")); String filePath = "C:/Users/Dash/Desktop/劳动合同(标准版).pdf"; PDFDocHelper2.signSinglePsw(filePath,list); System.out.println("------------结束时间:"+new Date()); }
2)代码实现
package com.test.itextTest; import com.itextpdf.text.BaseColor; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.test.model.PdfItextModel; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; /** * @Author * @Date 19:25 2020/3/7 * @Description */ public class PDFDocHelper2 { // 获取基础文字 public static BaseFont getBaseFont() throws DocumentException, IOException { BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false); return base; } /** * * @param oldPswFilePath 原来的文件地址 * @param list 需要添加的详细信息 * @return * @throws IOException * @throws DocumentException */ public static String signSinglePsw(String oldPswFilePath, List<PdfItextModel> list) throws IOException, DocumentException { int lastIndex = oldPswFilePath.lastIndexOf('.'); // 获取文件后缀 String suffix = oldPswFilePath.substring(lastIndex + 1); // 判断是否为pdf文件 if (!"pdf".equals(suffix.toLowerCase())) { throw new RuntimeException("Not is PDF file"); } // 生成新的文件路径 String newPswPath = oldPswFilePath.substring(0, lastIndex) + "-副本." + suffix; System.out.println("单个psw文件签名生成的新路径:" + newPswPath); //解析文件 PdfReader reader = new PdfReader(oldPswFilePath); FileOutputStream fOut = new FileOutputStream(newPswPath); PdfStamper stp = new PdfStamper(reader, fOut); // 总页数 System.out.println("PDF总页数:" + reader.getNumberOfPages()); for (PdfItextModel model : list) { Float xCoordinate = model.getxCoordinate(); Float yCoordinate = model.getyCoordinate(); Integer pageNum = model.getPageNum(); String content = model.getContent(); if(xCoordinate == null || yCoordinate == null || pageNum == null || pageNum == 0 || content == null || "".equals(content)){ continue; } PdfContentByte pdfContentByte = stp.getOverContent(pageNum); pdfContentByte.beginText(); // 设置字体及字号 pdfContentByte.setFontAndSize(getBaseFont(), 16); addDeptReview(xCoordinate,yCoordinate,pdfContentByte, content); pdfContentByte.endText(); } stp.close(); // 将输出流关闭 fOut.close(); reader.close(); // 文件读写结束 System.out.println("PSW文件读写完毕"); return newPswPath; } /** * @Author * @Date 18:48 2020/3/7 * @Description 添加水印 * @param content * @param keyword * @param x X轴坐标 * @param y Y轴坐标 */ private static void addDeptReview(float x,float y,PdfContentByte content, String keyword) { content.setColorFill(BaseColor.BLACK); // 设置水印位置和内容 System.out.println("水印内容:" + keyword); System.out.println("打印位置坐标:" + x + "," + y); content.showTextAligned(Element.ALIGN_LEFT, keyword, x, y, 0); } }
三、效果展示