一、重点说明
两种方法,方法1:通过documents4j 实现word转pdf,但是对Linux系统不友好,有坑有坑有坑,别问,问就是我一开始就用documents4j ,结果上版本发现一直转不了pdf,看日志找资料发现不支持Linux。若要支持Linux但是过程麻烦,需要Linux安装offic组件,不嫌麻烦可以试着找找如何安装offic组件资料。方法2:基于aspose-words,功能强大,在linux上可以完美使用。缺点就是是付费的,如果条件允许建议忽略下方的license.xml去使用正版。我用的是方法2,参考如下:
二、方法2(基于aspose-words)
1.jar下载
首先需要aspose-words-15.8.0-jdk16.jar包,有位老哥提供了资源,
链接: https://pan.baidu.com/s/13TIfBGFDgDJlxVonzUpgQQ 提取码: sbkg
2.jar放到本地仓库里面
<dependency>
<groupId>com.aspose</groupId>
<artifactId>words</artifactId>
<version>15.8.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.3</version>
</dependency>
mvn install:install-file -Dfile="E:\安装包\Java\aspose-words-15.8.0-jdk16.jar" -DgroupId=com.aspose -DartifactId=words -Dversion=15.8.0 -Dpackaging=jar
注:
-Dfile是你下载jar的本地路径
-DgroupId 是dependency里的groupId
-DartifactId是dependency里的artifactId
-Dversion是dependency里的version
3.引入license.xml
自己创建license.xml文件到resources下任意位置
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>
4.pdfUtil工具类
/** * 生成pdf文档 * @param Address 源文件地址 如 /root/example.doc * @param Address1 目标文件地址 如 /root/example.pdf */public class PdfUtil { public static void doc2pdf(String Address,String Address1) { // 验证License 若不验证则转化出的pdf文档会有水印产生 if (!getLicense()) { return; } try { //新建一个空白pdf文档 long old = System.currentTimeMillis(); File file = new File(Address1); FileOutputStream os = new FileOutputStream(file); //Address是将要被转化的word文档 Document doc = new Document(Address); //全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument,PDF,EPUB,XPS,SWF相互转换 doc.save(os, SaveFormat.PDF); long now = System.currentTimeMillis(); //转化用时 System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); } catch (Exception e) { e.printStackTrace(); } }}
5.转换好pdf后,对pdf进行盖章操作,盖一个3行1列表格章,如下图:
PdfUtil.doc2pdf(file, pdf); PDDocument document = PDDocument.load(new File(pdf)); // 获取第一页 PDPage firstPage = document.getPage(0); PDFont font = PDType0Font.load(document, new File(FILE_BASE_URL + File.separator + FILE_DEMO_URL + File.separator + "方正书宋.TTF")); // 获取页面尺寸 PDRectangle pageSize = firstPage.getMediaBox(); float pageWidth = pageSize.getWidth(); float pageHeight = pageSize.getHeight(); // 创建内容流 PDPageContentStream contentStream = new PDPageContentStream(document, firstPage, PDPageContentStream.AppendMode.APPEND, true, true); // 设置文本字体和大小 contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12); contentStream.setNonStrokingColor(0, 0, 255); // 设置线条颜色为蓝色 contentStream.setStrokingColor(0, 0, 255); // 绘制内外线框 float startX = 80; // 起始X坐标 float startY = pageHeight - 80; // 起始Y坐标 float cellWidth = 100; // 单元格宽度 float cellHeight = 20; // 单元格高度 // 绘制表格印章 for (int i = 0; i < 3; i++) { float x = startX; float y = startY - (i * cellHeight); contentStream.addRect(x, y, cellWidth, cellHeight); contentStream.stroke(); String text = ""; // 添加文字 if (i == 0) { text = " **** "; } if (i == 1) { text = "****(" + filingDetails.getFilingYear() + ")" + filingDetails.getNum() + "号"; } if (i == 2) { text = " ***** "; } contentStream.beginText(); contentStream.newLineAtOffset(x + 5, y + 5); contentStream.setFont(font, 8); contentStream.showText(new String(text.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8)); contentStream.endText(); } contentStream.close(); // 保存修改后的PDF文件 document.save(pdf); document.close(); //将pdf导出 String pdfName = pdf.substring(file.lastIndexOf("/") + 1); CommonUtils.setResponseHeader(response, pdfName); InputStream is = Files.newInputStream(Paths.get(pdf)); OutputStream os = new BufferedOutputStream(response.getOutputStream()); //创建存放文件内容的数组 byte[] buff = new byte[1024]; //所读取的内容使用n来接收 int n; //当没有读取完时,继续读取,循环 while ((n = is.read(buff)) != -1) { //将字节数组的数据全部写入到输出流中 os.write(buff, 0, n); } os.flush(); os.close(); is.close(); } catch (IOException e) { e.printStackTrace(); }
注:
方正书宋.TTF 可根据自己情况替换
链接:https://pan.baidu.com/s/1cW_T-ut0bJ91Lg1Lj11g4A?pwd=2333
提取码:2333