摘要:
了解jacob的程序员都知道,jacob是在java与微软的com组件之间的桥梁,通过使用jacob自带的dll动态链接库通过jni的方式实现了在sun java平台上的程序对com调用。本文介绍了如何使用jacob实现以下功能:写word文件;调用word文件中的宏;word文档转换为PDF文件的功能文章工具
如何使用jacob将word转换为PDF
版权声明:任何获得Matrix授权的网站,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:cleverpig( http://www.matrix.org.cn/blog/cleverpig)
原文: http://www.matrix.org.cn/resource/article/43/43923_jacob_word_PDF.html
关键字:jacob,word,pdf,com组件
前言:
了解jacob的程序员都知道,jacob是在java与微软的com组件之间的桥梁,通过使用jacob自带的dll动态链接库通过jni的方式实现了在sun java平台上的程序对com调用。jacob的作者照搬了微软java开发包中调用com组件的模式,并将它在sun java平台上实现,可谓是用心良苦啊。
在这里,我们要向jacob的开发者-Dan Adler致敬,感谢他的开源精神和其团队的伟大贡献!
一、代码实现功能介绍:
1.写word文件;
2.调用word文件中的宏;
3.word文档转换为PDF文件的功能。
二、使用的环境条件:
正是由于jacob的jni这种特性,所以运行jacob的机器上必须要有jacob.dll在系统的path中,而且还要有相应的被调用的com组件存在。
下面列表说明了本项目使用的软件环境和一些注意事项:
1.Word2003、Adobe Acrobat 7.0.5 Professional(由7.0版在线升级获得,因为7.0版存在bug);
2.并且关闭了Adobe PDF打印机属性->Adobe PDF Setting中的“do not send fonts to PDF”选项;
3.设置了Adobe PDF打印机属性->常规->打印首选项->布局->高级->文档选项->postscript options->TrueType font download option为Native TrueType。
第3个条件是可选的,第1、2个条件是必须的。不然会可能出现下面的错误:
三、源代码:
Dispatch_MSWord.java:
package com.bjinfotech.practice.jacob; import com.jacob.com.*; import com.jacob.activeX.*; /** * 使用jacob实现以下功能: * 写word文件; * 调用word文件中的宏; * word文档转换为PDF文件的功能。 * * 注意——使用的环境条件: * 1.Word2003、Adobe Acrobat 7.0.5 Professional(由7.0版在线升级获得,因为7.0版存在bug); * 2.并且关闭了Adobe PDF打印机属性->Adobe PDF Setting中的“do not send fonts to PDF”选项; * 3.设置了Adobe PDF打印机属性->常规->打印首选项->布局->高级->文档选项->postscript options->TrueType font download option为Native TrueType。 * 第3个条件是可选的,第1、2个条件是必须的。不然会可能出现错误。 * * 参考资源: * Create PDF files from Microsoft Excel using Acrobat (6.0 and 7.0 on Windows): * http://www.adobe.com/support/techdocs/328398.html * Article-Word Doc to PDF Conversion * http://www.suodenjoki.dk/us/productions/articles/word2pdf.htm * 微软的javasdk文档和adobe的Distiller api文档(在项目的dependencies目录中) * @author 聪明的猪 * */ public class Dispatch_MSWord { private ActiveXComponent wordCom=null; private Object wordDoc=null; private final Variant False=new Variant(false); private final Variant True=new Variant(true); /** * 打开word文档 * @param filePath word文档 * @return 返回word文档对象 */ public boolean openWord(String filePath){ //建立ActiveX部件 wordCom=new ActiveXComponent("Word.Application"); try{ //返回wrdCom.Documents的Dispatch Object wrdDocs=wordCom.getProperty("Documents").toDispatch(); //调用wrdCom.Documents.Open方法打开指定的word文档,返回wordDoc wordDoc=Dispatch.invoke(wrdDocs,"Open",Dispatch.Method,new Object[]{filePath},new int[1]).toDispatch(); return true; } catch(Exception ex){ ex.printStackTrace(); } return false; } /** * 关闭word文档 */ public void closeWord(){ //关闭word文件 wordCom.invoke("Quit",new Variant[]{}); } /** * 打开word,调用word中的宏 * @param filePath word文件路径 * @param macroName 被调用的宏名字 * @param parameter 调用宏的参数数组 */ public void callWordMacro(String filePath,String macroName,Object parameter[]){ if (!openWord(filePath)){ closeWord(); return; } else{ //使用方法传入的参数parameter调用word文档中的MyWordMacro宏 Dispatch.invoke(wordDoc,macroName,Dispatch.Method,parameter,new int[1]); closeWord(); } } /** * 打开word,替换其中的文字 * @param filePath word文件路径 * @param sourceStr 源文字 * @param replaceStr 替换后的文字 */ public void callReplaceWord(String filePath,String sourceStr,String replaceStr){ if (!openWord(filePath)){ closeWord(); return; } try{ //获得Selection对象 Dispatch selectDoc=wordCom.getProperty("Selection").toDispatch(); //获得Find对象 Dispatch find = Dispatch.call(selectDoc,"Find").toDispatch(); //设置替换的方法属性,但是不支持ReplaceWith的属性,而且使用Replancement.Text属性也无济于事。 Dispatch.put(find,"Text",sourceStr); //所以使用Find对象的Execute(FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, Replace, MatchKashida, MatchDiacritics, MatchAlefHamza, MatchControl)方法 //详细内容见MSDN的office2000开发文档 Variant True=new Variant(true); Variant False=new Variant(false); Variant FindText=new Variant(sourceStr); Variant ReplaceWith=new Variant(replaceStr); Variant Format=False; Variant Forward=True; Variant MatchCase=True; Variant MatchWholeWord=True; Variant MatchWildcards=False; Variant MatchSoundsLike=False; Variant MatchAllWordForms=False; int wdFindWrap_FindContinue=1; Variant Wrap=new Variant(wdFindWrap_FindContinue); int wdReplace_ReplaceAll=2; Variant Replace=new Variant(wdReplace_ReplaceAll); //使用callN方法调用execute方法 Dispatch.callN(find,"Execute",new Variant[]{ FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, Replace }); Dispatch.invoke(wordDoc,"SaveAs",Dispatch.Method,new Object[]{"c://111.doc"},new int[1]); closeWord(); } catch(Exception ex){ ex.printStackTrace(); } finally{ closeWord(); } } /** * 将word文档打印为PS文件后,使用Distiller将PS文件转换为PDF文件 * @param sourceFilePath 源文件路径 * @param destinPSFilePath 首先生成的PS文件路径 * @param destinPDFFilePath 生成PDF文件路径 */ public void docToPDF(String sourceFilePath,String destinPSFilePath,String destinPDFFilePath){ if (!openWord(sourceFilePath)){ closeWord(); return; } //建立Adobe Distiller的com对象 ActiveXComponent distiller=new ActiveXComponent("PDFDistiller.PDFDistiller.1"); try{ //设置当前使用的打印机,我的Adobe Distiller打印机名字为"Adobe PDF" wordCom.setProperty("ActivePrinter",new Variant("Adobe PDF")); //设置printout的参数,将word文档打印为postscript文档。目前只使用了前5个参数,如果要使用更多的话可以参考MSDN的office开发相关api //是否在后台运行 Variant Background=False; //是否追加打印 Variant Append =False; //打印所有文档 int wdPrintAllDocument=0; Variant Range =new Variant(wdPrintAllDocument); //输出的postscript文件的路径 Variant OutputFileName =new Variant(destinPSFilePath); // Variant From =new Variant(1); // Variant To =new Variant(1); // int wdPrintDocumentContent=2; // Variant Item =new Variant(wdPrintDocumentContent); // Variant Copies =new Variant(1); // Variant Pages =new Variant(); // int wdPrintAllPages=0; // Variant PageType =new Variant(wdPrintAllPages); // Variant PrintToFile =True; // Variant Collate =True; // Variant FileName =new Variant(sourceFilePath); // Variant ActivePrinterMacGX =new Variant(); // Variant ManualDuplexPrint =False; // Variant PrintZoomColumn =new Variant(); // Variant PrintZoomRow =new Variant(); // Variant PrintZoomPaperWidth =new Variant(); // Variant PrintZoomPaperHeight =new Variant(); // // Variant[] args=new Variant[]{Background,Append,Range,OutputFileName,From,To,Item,Copies,Pages,PageType, // PrintToFile,Collate,FileName,ActivePrinterMacGX,ManualDuplexPrint,PrintZoomColumn,PrintZoomRow, // PrintZoomPaperWidth,PrintZoomPaperHeight}; //调用word文档对象的PrintOut方法:将word文档打印为postscript文档,简称ps文档 Dispatch.callN(wordDoc, "PrintOut", new Variant[]{Background,Append,Range,OutputFileName}) ; System.out.println("由word文档打印为ps文档成功!"); //调用Distiller对象的FileToPDF方法所用的参数,详细内容参考Distiller Api手册 //作为输入的ps文档路径 Variant inputPostScriptFilePath=new Variant(destinPSFilePath); //作为输出的pdf文档的路径 Variant outputPDFFilePath=new Variant(destinPDFFilePath); //定义FileToPDF方法要使用adobe pdf设置文件的路径,在这里没有赋值表示并不使用pdf配置文件 Variant PDFOption=new Variant(""); //调用FileToPDF方法将ps文档转换为pdf文档 Dispatch.callN(distiller,"FileToPDF",new Variant[]{inputPostScriptFilePath,outputPDFFilePath,PDFOption}); System.out.println("由ps文档转换为pdf文档成功!"); } catch(Exception ex){ ex.printStackTrace(); } finally{ closeWord(); } } public static void main(String[] argv){ Dispatch_MSWord d=new Dispatch_MSWord(); // d.callWordMacro("E:/eclipse3.1RC3/workspace/jacobPractice/src/com/bjinfotech/practice/jacob/MacroTest.doc","MyWordMacro",new String[]{"这是调用word宏的测试程序"}); // d.callReplaceWord("E:/eclipse3.1RC3/workspace/jacobPractice/src/com/bjinfotech/practice/jacob/MacroTest.doc","$TITLE___FCKpd___0quot;,"文字已经被替换"); d.docToPDF("E:/eclipse3.1RC3/workspace/jacobPractice/src/com/bjinfotech/practice/jacob/MacroTest.doc","c:/1p.ps","c:/1p.pdf"); } }
四、参考资源:
·Matrix-Java开发者社区: http://www.matrix.org.cn/
·Jacob和Apache poi相关讨论: http://www.matrix.org.cn/forum.shtml
· Create PDF files from Microsoft Excel using Acrobat (6.0 and 7.0 on Windows)
· Article-Word Doc to PDF Conversion
微软的javasdk文档和adobe的Distiller api文档(在项目的dependencies目录中)
五、源代码下载:
源代码中包含了微软java sdk手册和adobe distiller api手册,所以分为5部分供大家下载。
·[ 下载文件]
·[ 下载文件]
·[ 下载文件]
·[ 下载文件]
·[ 下载文件]