Java中常用的几种DOCX转PDF方法

点击查看全文


DOCX2PDF

将DOCX文档转化为PDF是项目中常见的需求之一,目前主流的方法可以分为两大类,一类是利用各种Office应用进行转换,譬如Microsoft Office、WPS以及LiberOffice,另一种是利用各种语言提供的对于Office文档读取的接口(譬如Apache POI)然后使用专门的PDFGenerator库,譬如IText进行PDF构建。总的来说,从样式上利用Office应用可以保证较好的样式,不过相对而言效率会比较低。其中Microsoft Office涉及版权,不可轻易使用(笔者所在公司就被抓包了),WPS目前使用比较广泛,不过存在超链接截断问题,即超过256个字符的超链接会被截断,LiberOffice的样式排版相对比较随意。而利用POI接口进行读取与生成的方式性能较好,适用于对于格式要求不是很高的情况。另外还有一些封装好的在线工具或者命令行工具,譬如docx2pdf与OfficeToPDF。

MicroSoft Office

本部分的核心代码如下,全部代码参考这里:

 
  1. private ActiveXComponent oleComponent = null
  2. private Dispatch activeDoc = null
  3. private final static String APP_ID = "Word.Application"
  4.  
  5. // Constants that map onto Word's WdSaveOptions enumeration and that 
  6. // may be passed to the close(int) method 
  7. public static final int DO_NOT_SAVE_CHANGES = 0; 
  8. public static final int PROMPT_TO_SAVE_CHANGES = -2; 
  9. public static final int SAVE_CHANGES = -1; 
  10.  
  11. // These constant values determine whether or not tha application 
  12. // instance will be displyed on the users screen or not
  13. public static final boolean VISIBLE = true
  14. public static final boolean HIDDEN = false
  15.  
  16. /** 
  17.  * Create a new instance of the JacobWordSearch class using the following 
  18.  * parameters. 
  19.  * 
  20.  * @param visibility A primitive boolean whose value will determine whether 
  21.  *                   or not the Word application will be visible to the user. Pass true 
  22.  *                   to display Word, false otherwise. 
  23.  */ 
  24. public OfficeConverter(boolean visibility) { 
  25.     this.oleComponent = new ActiveXComponent(OfficeConverter.APP_ID); 
  26.     this.oleComponent.setProperty("Visible", new Variant(visibility)); 
  27.  
  28. /** 
  29.  * Open ana existing Word document. 
  30.  * 
  31.  * @param docName An instance of the String class that encapsulates the 
  32.  *                path to and name of a valid Word file. Note that there are a few 
  33.  *                limitations applying to the format of this String; it must specify 
  34.  *                the absolute path to the file and it must not use the single forward 
  35.  *                slash to specify the path separator. 
  36.  */ 
  37. public void openDoc(String docName) { 
  38.     Dispatch disp = null
  39.     Variant var = null
  40.     // First get a Dispatch object referencing the Documents collection - for 
  41.     // collections, think of ArrayLists of objects. 
  42.     var = Dispatch.get(this.oleComponent, "Documents"); 
  43.     disp = var.getDispatch(); 
  44.     // Now call the Open method on the Documents collection Dispatch object 
  45.     // to both open the file and add it to the collection. It would be possible 
  46.     // to open a series of files and access each from the Documents collection 
  47.     // but for this example, it is simpler to store a reference to the 
  48.     // active document in a private instance variable. 
  49.     var = Dispatch.call(disp, "Open", docName); 
  50.     this.activeDoc = var.getDispatch(); 
  51.  
  52. /** 
  53.  * There is more than one way to convert the document into PDF format, you 
  54.  * can either explicitly use a FileConvertor object or call the 
  55.  * ExportAsFixedFormat method on the active document. This method opts for 
  56.  * the latter and calls the ExportAsFixedFormat method passing the name 
  57.  * of the file along with the integer value of 17. This value maps onto one 
  58.  * of Word's constants called wdExportFormatPDF and causes the application 
  59.  * to convert the file into PDF format. If you wanted to do so, for testing 
  60.  * purposes, you could add another value to the args array, a Boolean value 
  61.  * of true. This would open the newly converted document automatically. 
  62.  * 
  63.  * @param filename 
  64.  */ 
  65. public void publishAsPDF(String filename) { 
  66.     // The code to expoort as a PDF is 17 
  67.     //Object args = new Object{filename, new Integer(17), new Boolean(true)}; 
  68.     Object args = new Object { 
  69.         filename, new Integer(17) 
  70.     } ; 
  71.     Dispatch.call(this.activeDoc, "ExportAsFixedFormat", args); 
  72.  
  73. /** 
  74.  * Called to close the active document. Note that this method simply 
  75.  * calls the overloaded closeDoc(int) method passing the value 0 which 
  76.  * instructs Word to close the document and discard any changes that may 
  77.  * have been made since the document was opened or edited. 
  78.  */ 
  79. public void closeDoc() { 
  80.     this.closeDoc(JacobWordSearch.DO_NOT_SAVE_CHANGES); 
  81.  
  82. /** 
  83.  * Called to close the active document. It is possible with this overloaded 
  84.  * version of the close() method to specify what should happen if the user 
  85.  * has made changes to the document that have not been saved. There are three 
  86.  * possible value defined by the following manifest constants; 
  87.  * DO_NOT_SAVE_CHANGES - Close the document and discard any changes 
  88.  * the user may have made. 
  89.  * PROMPT_TO_SAVE_CHANGES - Display a prompt to the user asking them 
  90.  * how to proceed. 
  91.  * SAVE_CHANGES - Save the changes the user has made to the document. 
  92.  * 
  93.  * @param saveOption A primitive integer whose value indicates how the close 
  94.  *                   operation should proceed if the user has made changes to the active 
  95.  *                   document. Note that no checks are made on the value passed to 
  96.  *                   this argument. 
  97.  */ 
  98. public void closeDoc(int saveOption) { 
  99.     Object args = {new Integer(saveOption)}; 
  100.     Dispatch.call(this.activeDoc, "Close", args); 
  101.  
  102. /** 
  103.  * Called once processing has completed in order to close down the instance 
  104.  * of Word. 
  105.  */ 
  106. public void quit() { 
  107.     Dispatch.call(this.oleComponent, "Quit"); 
  108. }  

WPS

Java调用WPS或pdfcreator的com接口实现doc转pdf

本文的核心代码如下,完整代码查看这里:

 
  1.  @Override 
  2.         public boolean convert(String word, String pdf) { 
  3.             File pdfFile = new File(pdf); 
  4.             File wordFile = new File(word); 
  5.             boolean convertSuccessfully = false
  6.  
  7.             ActiveXComponent wps = null
  8.             ActiveXComponent doc = null
  9.  
  10.  
  11.             try { 
  12.                 wps = new ActiveXComponent("KWPS.Application"); 
  13.  
  14. //                Dispatch docs = wps.getProperty("Documents").toDispatch(); 
  15. //                Dispatch d = Dispatch.call(docs, "Open", wordFile.getAbsolutePath(), falsetrue).toDispatch(); 
  16. //                Dispatch.call(d, "SaveAs", pdfFile.getAbsolutePath(), 17); 
  17. //                Dispatch.call(d, "Close"false); 
  18.  
  19.                 doc = wps.invokeGetComponent("Documents"
  20.                         .invokeGetComponent("Open", new Variant(wordFile.getAbsolutePath())); 
  21.  
  22.                 try { 
  23.                     doc.invoke("SaveAs"
  24.                             new Variant(new File("C:\\Users\\lotuc\\Documents\\mmm.pdf").getAbsolutePath()), 
  25.                             new Variant(17)); 
  26.                     convertSuccessfully = true
  27.                 } catch (Exception e) { 
  28.                     logger.warning("生成PDF失败"); 
  29.                     e.printStackTrace(); 
  30.                 } 
  31.  
  32.                 File saveAsFile = new File("C:\\Users\\lotuc\\Documents\\saveasfile.doc"); 
  33.                 try { 
  34.                     doc.invoke("SaveAs", saveAsFile.getAbsolutePath()); 
  35.                     logger.info("成功另存为" + saveAsFile.getAbsolutePath()); 
  36.                 } catch (Exception e) { 
  37.                     logger.info("另存为" + saveAsFile.getAbsolutePath() + "失败"); 
  38.                     e.printStackTrace(); 
  39.                 } 
  40.             } finally { 
  41.                 if (doc == null) { 
  42.                     logger.info("打开文件 " + wordFile.getAbsolutePath() + " 失败"); 
  43.                 } else { 
  44.                     try { 
  45.                         logger.info("释放文件 " + wordFile.getAbsolutePath()); 
  46.                         doc.invoke("Close"); 
  47.                         doc.safeRelease(); 
  48.                     } catch (Exception e1) { 
  49.                         logger.info("释放文件 " + wordFile.getAbsolutePath() + " 失败"); 
  50.                     } 
  51.                 } 
  52.  
  53.                 if (wps == null) { 
  54.                     logger.info("加载 WPS 控件失败"); 
  55.                 } else { 
  56.                     try { 
  57.                         logger.info("释放 WPS 控件"); 
  58.                         wps.invoke("Quit"); 
  59.                         wps.safeRelease(); 
  60.                     } catch (Exception e1) { 
  61.                         logger.info("释放 WPS 控件失败"); 
  62.                     } 
  63.                 } 
  64.             } 
  65.  
  66.             return convertSuccessfully; 
  67.         }  

LiberOffice



点击查看全文


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用Apache POI和Apache PDFBox库来实现将docx文件换为pdf并添加对勾的功能。 首先,使用Apache POI读取docx文件并提取文本内容。然后,使用Apache PDFBox创建一个新的pdf文件,并将文本内容添加到pdf文件。最后,使用PDFBox提供的绘图功能在pdf文件绘制对勾。 以下是一个简单的示例代码: ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.graphics.color.PDColor; import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB; import org.apache.pdfbox.pdmodel.graphics.color.PDGamma; public class DocxToPdfWithCheckMark { public static void main(String[] args) { try { // Read docx file XWPFDocument doc = new XWPFDocument(new FileInputStream("input.docx")); // Extract text from docx file StringBuilder text = new StringBuilder(); for (XWPFParagraph p : doc.getParagraphs()) { for (XWPFRun r : p.getRuns()) { text.append(r.getText(0)).append("\n"); } } // Create new pdf document PDDocument pdfDoc = new PDDocument(); PDPage page = new PDPage(); pdfDoc.addPage(page); // Add text to pdf document PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, page); contentStream.beginText(); contentStream.setFont(PDType1Font.HELVETICA, 12); contentStream.newLineAtOffset(100, 700); contentStream.showText(text.toString()); contentStream.endText(); // Add check mark to pdf document PDGamma color = new PDGamma(); color.setR(0); color.setG(0); color.setB(0); PDColor pdColor = new PDColor(color, PDDeviceRGB.INSTANCE); contentStream.setNonStrokingColor(pdColor); contentStream.moveTo(50, 650); contentStream.lineTo(60, 640); contentStream.lineTo(70, 660); contentStream.lineTo(80, 630); contentStream.stroke(); contentStream.close(); // Save pdf document pdfDoc.save(new FileOutputStream("output.pdf")); pdfDoc.close(); } catch (Exception ex) { ex.printStackTrace(); } } } ``` 在上面的代码,我们首先使用Apache POI读取docx文件并提取文本内容。然后,我们使用PDFBox创建一个新的pdf文件,并将文本内容添加到pdf文件。最后,我们使用PDFBox的绘图功能在pdf文件绘制对勾。注意,绘制对勾的坐标需要根据文本内容的位置进行调整,以确保对勾的位置正确。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值