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. /**
30. * Open ana existing Word document.
31. *
32. * @param docName An instance of the String class that encapsulates the
33. * path to and name of a valid Word file. Note that there are a few
34. * limitations applying to the format of this String; it must specify
35. * the absolute path to the file and it must not use the single forward
36. * slash to specify the path separator.
37. */
38. public void openDoc(String docName) {
39. Dispatch disp = null;
40. Variant var = null;
41. // First get a Dispatch object referencing the Documents collection - for
42. // collections, think of ArrayLists of objects.
43. var = (this.oleComponent, "Documents");
44. disp = Dispatch();
45. // Now call the Open method on the Documents collection Dispatch object
46. // to both open the file and add it to the collection. It would be possible
47. // to open a series of files and access each from the Documents collection
48. // but for this example, it is simpler to store a reference to the
49. // active document in a private instance variable.
50. var = Dispatch.call(disp, "Open", docName);
51. this.activeDoc = Dispatch();
52. }
53.
54. /**
55. * There is more than one way to convert the document into PDF format, you
56. * can either explicitly use a FileConvertor object or call the
57. * ExportAsFixedFormat method on the active document. This method opts for
58. * the latter and calls the ExportAsFixedFormat method passing the name
59. * of the file along with the integer value of 17. This value maps onto one
getsavefilename60. * of Word's constants called wdExportFormatPDF and causes the application
61. * to convert the file into PDF format. If you wanted to do so, for testing
62. * purposes, you could add another value to the args array, a Boolean value
63. * of true. This would open the newly converted document automatically.
64. *
65. * @param filename
66. */
67. public void publishAsPDF(String filename) {
68. // The code to expoort as a PDF is 17
69. //Object args = new Object{filename, new Integer(17), new Boolean(true)};
70. Object args = new Object {
71. filename, new Integer(17)
72. } ;
73. Dispatch.call(this.activeDoc, "ExportAsFixedFormat", args);
74. }
75.
76. /**
77. * Called to close the active document. Note that this method simply
78. * calls the overloaded closeDoc(int) method passing the value 0 which
79. * instructs Word to close the document and discard any changes that may
80. * have been made since the document was opened or edited.
82. public void closeDoc() {
83. this.closeDoc(JacobWordSearch.DO_NOT_SAVE_CHANGES);
84. }
85.
86. /**
87. * Called to close the active document. It is possible with this overloaded
88. * version of the close() method to specify what should happen if the user
89. * has made changes to the document that have not been saved. There are three
90. * possible value defined by the following manifest constants;
91. * DO_NOT_SAVE_CHANGES - Close the document and discard any changes
92. * the user may have made.
93. * PROMPT_TO_SAVE_CHANGES - Display a prompt to the user asking them
94. * how to proceed.
95. * SAVE_CHANGES - Save the changes the user has made to the document.
96. *
97. * @param saveOption A primitive integer whose value indicates how the close
98. * operation should proceed if the user has made changes to the active
99. * document. Note that no checks are made on the value passed to 100. * this argument.
101. */
102. public void closeDoc(int saveOption) {
103. Object args = {new Integer(saveOption)};
104. Dispatch.call(this.activeDoc, "Close", args);
105. }
106.
107. /**
108. * Called once processing has completed in order to close down the instance 109. * of Word.
110. */
111. public void quit() {
112. Dispatch.call(this.oleComponent, "Quit");
113. }
WPS
本⽂的核⼼代码如下,完整代码查看这⾥:
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.
11. try {
12. wps = new ActiveXComponent("KWPS.Application");
13.
14. // Dispatch docs = Property("Documents").toDispatch();
15. // Dispatch d = Dispatch.call(docs, "Open", AbsolutePath(), false, true).toDispatch();
16. // Dispatch.call(d, "SaveAs", AbsolutePath(), 17);
17. // Dispatch.call(d, "Close", false);
18.
19. doc = wps.invokeGetComponent("Documents")
20. .invokeGetComponent("Open", new AbsolutePath()));
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", AbsolutePath());
35. logger.info("成功另存为" + AbsolutePath());
36. } catch (Exception e) {
37. logger.info("另存为" + AbsolutePath() + "失败");
38. e.printStackTrace();
39. }
40. } finally {
41. if (doc == null) {
42. logger.info("打开⽂件 " + AbsolutePath() + " 失败");
43. } else {
44. try {
45. logger.info("释放⽂件 " + AbsolutePath());
46. doc.invoke("Close");
47. doc.safeRelease();
48. } catch (Exception e1) {
49. logger.info("释放⽂件 " + AbsolutePath() + " 失败");
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
LiberOffice本⾝提供了⼀个命令⾏⼯具进⾏转换,在你安装好了LiberOffice之后
1. /usr/local/bin/soffice --convert-to pdf:writer_pdf_Export /Users/lotuc/Downloads/test.doc
如果有打开的libreoffice实例, 要穿⼊env选项指定⼀个⼯作⽬录
1. /usr/local/bin/soffice "-env:UserInstallation=file:///tmp/LibreOffice_Conversion_abc" --convert-
to pdf:writer_pdf_Export /Users/lotuc/Downloads/test.doc
⾸先我们需要安装好LiberOffice,然后将依赖的Jar包添加到classpath中:I
1. Install Libre Office
2.
3. Create a Java project in your favorite editor and add these to your class path:
4. [Libre Office Dir]/URE/java/juh.jar
5. [Libre Office Dir]/URE/java/jurt.jar
6. [Libre Office Dir]/URE/java/ridl.jar
7. [Libre Office Dir]/program/classes/unoil.jar
然后我们需要启动⼀个LiberOffice进程:
1. import java.util.Date;
2. import java.io.File;
3. import com.sun.star.beans.PropertyValue;
4. import com.sun.starp.helper.Bootstrap;
5. import com.sun.star.frame.XComponentLoader;
6. import com.sun.star.frame.XDesktop;
7. import com.sun.star.frame.XStorable;
8. import com.sun.star.lang.XComponent;
9. import com.sun.star.lang.XMultiComponentFactory;
10. import com.XTextDocument;
11. import com.sun.star.uno.UnoRuntime;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论