一、使用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); } }
三、效果展示