锁定老帖子 主题:DOC文档转PDF
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-04-17
最后修改:2011-04-17
下面把尝试的情况记录下来,也希望做过类似工作的童鞋能一起探讨一下。 我尝试过的Word文档转PDF,用过两种方法: 1、使用OpenOffice转PDF; 2、使用MS Office的OLE自动化功能; OpenOffice的情况稍后补充,下面先说MS Office的转换情况。 Office版本使用2007,因为2007提供了一个加载项:Microsoft Save as PDF 或 XPS,可将文档另存为PDF格式。下载地址:http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=4D951911-3E7E-4AE6-B059-A2E79ED87041,安装即可使用。 Office COM 组件调用使用jacob(Java COM Bridge) http://sourceforge.net/projects/jacob-project/ Jacob初次使用的人可能会感到比较困惑。题外话,jacob的API设计是有够别扭的,这儿就不多说了。下面说明一下: 我们接触的jacob类主要就3个:ActiveXComponent、Variant、Dispatch; ActiveXComponent代表COM应用程序: 初始化方法为: ActiveXComponent app = new ActiveXComponent("Word.Application"); Variant 是与COM通讯的参数或者返回值; Dispatch代表一个可操作的自动化对象;如果确定返回值是自动化对象的话,可以调用Variant.toDispatch()转换成Dispatch。 获取了Dispatch之后,即可调用该自动化对象的属性或方法,具体的属性和方法要看参考文档,比如:Word开发可在WORD帮助中查看“脱机开发人员帮助WORD对象模型”。 Dispatch.get(dispatch, String name);获取对象属性; Dispatch.put(dispatch, String name, Object value);设置对象属性; Dispatch.call(dispatch, String name, Object… args);调用对象方法; 以上都是Dispatch上的静态方法,所以需要传递dispatch本身。 关于jacob-1.15-M4-x86.dll放置的位置,其实很简单,dll的放置位置就是系统参数 System.getProperty("java.library.path");所指定的,放在路径里的任意一个目录即可,不想污染JDK目录或者windows/system32目录的话,放置项目启动目录下就可以了,Eclipse下我是放在项目目录下。 下面看具体代码: public class Word2PDF { static final int wdDoNotSaveChanges = 0;// 不保存待定的更改。 static final int wdFormatPDF = 17;// PDF 格式 public static void main(String[] args) { String filename = "f:/temp/测试文档.docx"; String toFilename = filename + ".pdf"; System.out.println("启动Word..."); long start = System.currentTimeMillis(); ActiveXComponent app = null; try { app = new ActiveXComponent("Word.Application"); app.setProperty("Visible", false); Dispatch docs = app.getProperty("Documents").toDispatch(); System.out.println("打开文档..." + filename); Dispatch doc = Dispatch.call(docs,// "Open", // filename,// FileName false,// ConfirmConversions true // ReadOnly ).toDispatch(); System.out.println("转换文档到PDF..." + toFilename); File tofile = new File(toFilename); if (tofile.exists()) { tofile.delete(); } Dispatch.call(doc,// "SaveAs", // toFilename, // FileName wdFormatPDF); Dispatch.call(doc, "Close", false); long end = System.currentTimeMillis(); System.out.println("转换完成..用时:" + (end - start) + "ms."); } catch (Exception e) { System.out.println("========Error:文档转换失败:" + e.getMessage()); } finally { if (app != null) app.invoke("Quit", wdDoNotSaveChanges); } } } 已知的情况: 1、转换效果好。(相对于OpenOffice) 2、速度慢 3、CPU占用率高 待解决的问题: 1、安全性问题:是否可禁用WORD宏,以及WORD文档中的ActiveX控件? 这一点我不太清楚,但在WORD选项--安全性设置中看到的: 2、微软知识库中的“服务器端 Office 自动化注意事项” http://support.microsoft.com/kb/257757/ 文档似乎明确了 Microsoft 目前建议不要从任何无人参与的、非交互式客户端应用程序或组件(包括 ASP、DCOM 和 NT Service)中进行 Microsoft Office 应用程序的“自动化”,也不为此提供支持,因为 Office 在这种环境中运行时可能会出现不稳定的现象并且/或者会死锁。 因为我主要的用途就是用来服务器端自动转换。 待仔细研读。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-04-17
因为使用WORD转PDF的效果是OpenOffice无法比拟的,虽然有诸多问题,还是想要采用。
因为已知的问题: 1、转换速度慢; 2、CPU占用率高(单CPU占用100%) 3、并发情况下WORD可能会死锁(微软知识库) 4、Word宏安全问题; 5、还有一些未知的细节。 目前的打算是采用一个独立服务器,定时扫描需要转换文档的数据库表, 一旦有任务就执行转换,转换完再取下一条数据。 这样的话1/2/3条都不成问题了。 |
|
返回顶楼 | |
发表时间:2011-04-18
1\2\3 跟转换的有关系。
4、可以对宏进行签名,解决安全问题。 ----------------------------------- 你可以咨询我任何office dev相关的问题。 另外,对你的几个建议 1、office不支持ole,可以通过dsoframer来做 2、office在com方式下使用,容易出现无法release的问题。特别是excel, 因为excel的进程模型跟其他的不太一样。 这个有办法处理强制解决。 还有一个转换办法: 使用office的print功能,而不是saveaspdf插件。 然后指定pdf reader自带的pdf打印机来生成文档。 当然,这些方式,都依赖了office。 |
|
返回顶楼 | |
发表时间:2011-04-18
TO kimmking:
非常感谢。 OLE是我前面写错了,目前暂不需要嵌入编辑界面,只需要后台运行Office就可以了。 如果用Office做后台转换的话,转换速度慢、CPU占用100%的问题还有什么好的办法来应对吗? 宏的问题,我主要担心恶意的宏对系统安全造成危害。 有什么办法来解决吗?Office我的使用还比较初级,呵呵 使用office的print功能,比使用saveas有哪些优势吗? 使用saveas只需要依赖office,使用print,依赖的环境不是更多了吗? 另外,关于你说的: kimmking 写道 2、office在com方式下使用,容易出现无法release的问题。特别是excel, 因为excel的进程模型跟其他的不太一样。 这个有办法处理强制解决。 非常有兴趣知道,期待你的分享。 |
|
返回顶楼 | |
发表时间:2011-06-09
在ppt转换为pdf时,visible可否有什么方法设置为false?
用setProperty尝试了下,提示不允许:Hiding the application window is not allowed。 |
|
返回顶楼 | |
发表时间:2011-06-09
xiangziwade 写道 在ppt转换为pdf时,visible可否有什么方法设置为false?
用setProperty尝试了下,提示不允许:Hiding the application window is not allowed。 app = new ActiveXComponent("Powerpoint.Application"); // app.setProperty("Visible", true); System.out.println(app.getProperty("Visible")); new一个Powerpoint.Application时,Visible已经是false了。 MsoTriState 枚举.msoFalse的值是0,和打印出来的相同。 反而是如果调用setProperty("Visible", true);Powerpoint的窗口才会显示出来。 不过一个问题是 另存的时候,还是会有一个发布的进度框显示出来,还不知道该怎样把它隐藏掉。 public class Test { static final int ppSaveAsPDF = 32;// PDF 格式 public static void main(String[] args) { String filename = "f:/aaaaa.ppt"; String toFilename = filename + ".pdf"; System.out.println("启动..."); long start = System.currentTimeMillis(); ActiveXComponent app = null; try { app = new ActiveXComponent("Powerpoint.Application"); // app.setProperty("Visible", true); System.out.println(app.getProperty("Visible")); Dispatch presentations = app.getProperty("Presentations").toDispatch(); System.out.println("打开文档..." + filename); Dispatch presentation = Dispatch.call(presentations,// "Open", // filename,// FileName true,// ReadOnly true,// Untitled 指定文件是否有标题。 false // WithWindow 指定文件是否可见。 ).toDispatch(); System.out.println("转换文档到PDF..." + toFilename); File tofile = new File(toFilename); if (tofile.exists()) { tofile.delete(); } Dispatch.call(presentation,// "SaveAs", // toFilename, // FileName ppSaveAsPDF); Dispatch.call(presentation, "Close"); long end = System.currentTimeMillis(); System.out.println("转换完成..用时:" + (end - start) + "ms."); } catch (Exception e) { System.out.println("========Error:文档转换失败:" + e.getMessage()); } finally { if (app != null) app.invoke("Quit"); } } |
|
返回顶楼 | |
发表时间:2011-06-09
装个PDF打印机就可以了,win7默认有XPS打印机,win8应该同时支持xps和PDF
|
|
返回顶楼 | |
发表时间:2011-06-09
原来如此啊,非常感谢!
Dispatch.call()的情况好复杂。。。 另外,这些常数是如何定义的呢? static final int wdFormatPDF = 17;// PDF 格式 static final int ppSaveAsPDF = 32;// PDF 格式 对于ppt貌似设置成16到19之间,可以直接转换成图片。 不知对于word有没有类似的情况? |
|
返回顶楼 | |
发表时间:2011-06-10
xiangziwade 写道 原来如此啊,非常感谢!
Dispatch.call()的情况好复杂。。。 另外,这些常数是如何定义的呢? static final int wdFormatPDF = 17;// PDF 格式 static final int ppSaveAsPDF = 32;// PDF 格式 对于ppt貌似设置成16到19之间,可以直接转换成图片。 不知对于word有没有类似的情况? sswh 写道 获取了Dispatch之后,即可调用该自动化对象的属性或方法,具体的属性和方法要看参考文档,比如:Word开发可在WORD帮助中查看“脱机开发人员帮助WORD对象模型”。
|
|
返回顶楼 | |
发表时间:2011-06-10
再次感谢您不吝赐教!!!
查看了一下,word貌似还真没有控制直接存为图片的参数。。。 另外,有没有什么 不依赖于office2007 来转换word2003到pdf(或者图片)的方法? |
|
返回顶楼 | |