OpenOffice.org开源办公套件将各类文档转为PDF(3)
总体来说,虽然OOo并没有提供优雅的API,但是它的主要“套路”还是比较容易摸索出来的:加载文档,使用UnoRuntime.queryInterface方法获取各种操作接口,而各种参数都通过PropertyValue数组来提供。如果您像我一样感觉不爽,重新作一层简单的封装也是十分容易的。
运行中的问题
到目前为止,我们只是重新整理了示例代码,还没有开始运行。当第一次运行的时候便发现有异常抛出:
com.sun.star.comp.helper.BootstrapException: no office executable found!
at com.sun.star.comp.helper.Bootstrap.bootstrap(Bootstrap.java:246)
at jeffz.practices.AnyToDoc.createContext(AnyToDoc.java:19)
at jeffz.practices.AnyToDoc.main(AnyToDoc.java:87)
不过有异常信息之后,查找解决方案一般也很容易(但就我个人经验来说,还是有很多朋友会问“抛出XX异常该怎么办”之类的问题)。经过搜索,发现遇到这个问题的人还不少,他们把juh.jar等文件复制到OOo安装目录外(这在生产环境中几乎是必然的)之后便会产生这个异常,但如果直接引用OOo安装目录内的jar便不会有问题了——但是我目前是直接引用OOo安装目录的jar包,不是吗?但我转念一想,我当时为编译通过而挣扎的原因,不就是“juh.jar”等文件不在它本该在的位置吗?既然这个问题和jar包与OOo程序的相对路径有关,那么如果我把jar包放回“原来”的位置,这个问题可能就不存在了。
不过这些只是推测,我没有去进行尝试。因为既然在生产环境中还是会破坏路径问题,那我还是找一下这个问题的解决方案吧。最终在OOo的论坛上找到了答案:有人提供了一个补充包bootstrapconnector.jar,其中提供了一个方法可以让我们指定OOo的程序目录。也就是说,我们需要把之前的createContext改写成:
private static XComponentContext createContext() throws Exception {
// get the remote office component context
// return Bootstrap.bootstrap();
String oooExeFolder = "C:/Program Files/OpenOffice.org 3/program/";
return BootstrapSocketConnector.bootstrap(oooExeFolder);
}
当然,生产环境中您一般不会使用硬编码的方式制定路径,您可以把它放在配置文件或是系统变量里。再次运行即告成功。这段代码会将一个txt文件转化成旧有的Word格式,事实上您可以将txt替换成OOo所支持的任何一种格式,比如rtf,docs,odt等等。
那么接下来的问题便是,如何将目标格式改为PDF文件?很显然,目标格式是Word文件,是因为我们将类型字符串指定为“swriter: MS Word 97”,那么PDF格式是多少?这靠猜测是没法得出结果的,最后还是从一篇文档中得到了答案:writer_pdf_Export。事实上,这么做还是不够,代码还是会在storeAsURL方法中抛出异常,而且这是一个泛泛的ErrorCodeIOException,没有具体信息(message为空)。又一阵好找,才发现storeAsURL对应着OOo的“Save as”功能,而如果是“Export”功能,则应该调用storeToURL方法。
最后,我们终于成功地将其他格式转化为PDF文件了。