2007年6月18日星期一

让java与OpenOffice调情-结晶

ok,你现在应该已经知道如何利用openoffice打开文档,应该也知道了如何编辑文档,现在我们需要一个最后但并非最不实用的功能,导出文档。

拜OpenOffice所赐,我们拥有完备的文档转换功能,可以自由的把文档导出成你期望的任何格式,这其中就包括我们相当期待的PDF格式

唔,let's go

首先自然是老规矩:获取操作接口
XStorable xstorable = ( XStorable ) UnoRuntime.queryInterface( XStorable.class,
xComp );
这儿必须注意一点,传入的对象实例是从xCompLoader.loadComponentFromURL获取的XComponent,网络流传的颇多文档在此误为xDocument,不知是OpenOffice版本沿革还是笔误所为。

接下来也是老规矩:为Props对象赋值
name=>FilterName
value=>writer_pdf_Export

说明我们导出的格式为PDF,其他pdf相关参数可以自行查询

然后最关键的一步:导出,这儿和OpenOffice其他地方一样,传递的也是一个Url而不是我们熟悉的File对象。
xstorable.storeToURL( stringUrl, propertyvalue );

如果你需要的话,释放文档对象
xComp.dispose();

ok,你应该可以得到一个PDF文档了,可以猜测到的,如果你把FilterName中的文字改为别的内容,你可以得到不同格式的文档。唔,美丽的世界

更多操作及功能选项请以OpenOffice SDK文档为准

2007年6月14日星期四

动荡的六月

唔,过去的日子发生了太多太多的事情

一场股市风暴在意料之内刮到,宣告了07年度股市风险培训班的开业,虽然课程只持续了短短几天,但是上千点的震荡已经足够让大多数股民顺利毕业,从此远离股海的惊涛骇浪,安于待在基金的避风港湾内小富即安

Norton意外的摆了一个相当大的乌龙,让无数太相信杀毒软件的用户遭遇蓝屏,这件事情本身已十分糟糕,而其后国内某同行借势大发枪稿,和KAV大打嘴仗则更为滑稽,而之后的索赔官司倒是可以做为一个不错的案例,不过,最最有看头的,还是前几日,某”著名IT评论人”跳将出来指Norton无罪,MS有鬼,戏演至此,下面会如何发展,已经无人知晓。只能安心看戏了。

杀毒软件的国产进口之争,结果还是比较明显的,有些东西就不那么明显了,比如Google vs Baidu,在Google接连拿下和Sina的合作以及开通免费短信服务之后,竞争的格局开始布满迷雾,同样看不透的是joyo和dangdang的大战。joyo在亚马逊老总访华前后大撒优惠券,而当当则报以一片片的公关软文。卓越面临的挑战到底有多大?中国C2B头把交椅是否真的已经易主,亚马逊会成为在中国倒下的下一个外资巨头么?

在另一个赛场上,国军已经毫无争议的输掉了竞赛,一个普通而又不普通的周末,上海体育台转播了远在万里之外的F1而舍弃了上海子弟军的中超足球大战,从国内开始全程直播F1的几年间,F1已经从典型的小众运动跃升到了和国内顶级足球联赛争夺观众的地位。不知道这算是F1在中国的成功,还是中国足球职业化改革的完败。

躁动的六月,上海迎来了电影节,而海盗,绿怪,金刚也将接连抵岸,炎炎夏日注定是属于好莱坞的,今年国产电影依然没有和好莱坞正面交锋的勇气,我们只好等待9月,去年好歹有三峡好人,有夜宴,今年不知道我们能不能看到王小帅,顾长卫交出答卷。

红楼演员的意外早逝,和轰轰烈烈的红楼选秀,重新激发了娱记们挖掘红楼8g的动力,在这个娱乐至死的年代,一切都会成为娱乐,即使是生老病死。只是可惜了红楼。

六月我们迎来了香港回归10年的纪念,弹指一挥间,香港已经回归10年,不知道,10年后的中国又会是怎样的容貌。

让java与OpenOffice调情-缠绵

OK,我们已经成功的把OpenOffice娶进了java的家门,下面,我们就可以自由的调动各种方法来处理我们的文档,从最简单的增加内容到很实用的查找替换。一切的一切,只要你可以在openoffic开发文档中找到,都可以方便的施予其身。

如果我们要添加一段文字,我们只需要简单的从Document获取Text对象

XText xText = document.getText();

然后获取一个文档指针控制文字的插入位置
XTextCursor xTCursor = xText.createTextCursor();

接下来就是常规工作了。唔,易如反掌
xText.insertString( xTCursor, "The first line in the newly created text document.\n", false );

如果我们需要使用查找替换的话,我们必须先获取一个替换操作类
XReplaceable xReplaceable = (XReplaceable) UnoRuntime.queryInterface(XReplaceable.class, document);

然后,告诉OpenOffice需要的关键参数,唔,也许你会发现这几乎是和软件的功能对话框中的选项一摸一样:
XReplaceDescriptor xRepDesc = xReplaceable.createReplaceDescriptor();
xRepDesc.setSearchString(searchContext);
xRepDesc.setReplaceString(replaceContext);

然后,用已经熟悉的方式,设置一些其他的参数,你应该可以在对应对话框中找到这些选项条目
XPropertyReplace xPropRepl = (XPropertyReplace)
UnoRuntime.queryInterface(XPropertyReplace.class, xRepDesc);
xPropRepl.setReplaceAttributes(new PropertyValue[0]);

OK

现在你需要的就是一步调用:

xReplaceable.replaceAll(xRepDesc);

大功告成

更多的操作,更多更多的操作,尽在OpenOfficeSDK文档

2007年6月7日星期四

第六十三加一条军规

根据一个完全不真实的新闻来源,一家不允许被提到的城市日报,因为一位员工不存在的疏忽,刊登了一条触犯了不存在的禁令的广告,然后完全没有被严加整顿。

唔,22条军规现实版

一个合格的公民,是不应该知道2的某次幂在神州大地的特殊含义的。但是,如果因为你不知道这个特殊的含义而太过自由的使用了它,那么你将因为无知而受到惩罚。也就是说,你会因为不知道一个不应知道的东西而违反军规

这是一片多么神奇的土地啊

2007年6月4日星期一

终于有垫背了


London 2012 - New brand launches

呃,对于2008奥运会的信心大大提升了,因为今天看到了约翰牛公布的2012奥运会会标。

唔,难以想象,这么一个现代派的几何拼贴造型就算是把奥运会代表了?估计这是有史以来最缺乏美感的标记,原本以为这是代表五大州,后来发现文案中好像丝毫未提,看来反而是我自作多情。好像这几个方块没有任何的抽象含义,就是这么几个方块,代表的是全民参与的精神,热忱,三个代表(咳)……

原本对2008北京奥运的印章人一直颇有腹绯,嫌其太过四平八稳,更适合做故宫文物展的标记而非运动会的标记,现在看到伦敦的会徽,我才发现那个印章人是多么的富有创意

不管2008北京奥运最后能否成功,有一点是肯定的,至少,我们的会徽比伦敦漂亮……

2007年6月1日星期五

让Java与OpenOffice调情-缘起

你在困扰于word文档,Excel文档,各种各样的Office文档处理么?
你在羡慕DotNet程序员可以自如操作MS Office底层接口么?
你在四处翻腾纯java的PDF文件转换方案么?

欢迎来到OpenOffice.Org的世界,在这儿,你能享受到VIP的待遇,通过标准的Java接口,你可以尽情享受OpenOffice的强大功能,而且,这一切,都是Free的!为自由软件运动欢呼吧。让上千元一套的MS Office见鬼去吧。Java世界也能拥有完备的,自由的Office解决方案。

来,让我们开启通向自由花园的大门。

首先,确保你的电脑中安装了openoffice,唔,放心,没有序列号,没有copyright,这是一个free software,接下来,推荐,但不是必须的,你可以安装一套OpenOffice的SDK,运行程序并不需要SDK,但是在SDK中你能找到大量的文档和示例,以及大量深层开发必须的东西。


你有两种调用OpenOffice的选择:

1.你可以在代码中直接启动OpenOffice,前提是你必须×直接×引用OpenOffice目录中的jar包(别试图直接copy它们到某个lib目录,你只会在个程序中收获一个错误信息),他们的位置是“安装目录”\program\classes\,你至少需要引用juh.jar,jurt.jar,ridl.jar,unoil.jar这四个jar。

然后写下如下的代码:
//============================
com.sun.star.uno.XComponentContext xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
log.info("Connected to a running office ...");

com.sun.star.lang.XMultiComponentFactory xMCF = xContext.getServiceManager();

Object oDesktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", Context);

com.sun.star.frame.XComponentLoader xCompLoader = (com.sun.star.frame.XComponentLoader)
UnoRuntime.queryInterface( com.sun.star.frame.XComponentLoader.class, oDesktop);

com.sun.star.lang.XComponent xComp = xCompLoader.loadComponentFromURL(
fileUrlPath, "_blank", 0, new com.sun.star.beans.PropertyValue[0]);
//=======================================

你也可以在SDK目录的examples\java\DocumentHandling\DocumentLoader.java中找到这段代码,唔,如果看不明白不用担心,你需要知道的就是一个对象创建了又一个对象直到你获得了一个xComponent对象为止。

提示1:这儿的fileUrlPath是一个指向需要操作的文件的url路径,也就是类似于File:///C:/document/mydoc.rtf,Http://192.168.5.3/files/abc.html之类的路径,在OpenOffice的API中,绝大多数路径都必须用这种方式来指定。

提示2:xComp会是我们实际工作的起点,后面很多很多操作都会基于它而工作。

如果这段代码执行正常,你会发现屏幕上弹出一个openoffice的启动窗口并且直接打开一个指定的文档。有些情况下,这是一个贴心的设计,但更多情况下,这是不太能忍受的,如果我们希望openoffice静默运行,我们必须给loadComponentFromURL()调用加上一个参数:hidden=true

需要指定参数,我们需要构建一个PropertyValue数组,包含一个PropertyValue对象,Name="Hidden",value=Boolean.True(注意,这儿必须传递一个Object),把它传递给loadCompeonentFromURL,你就不会看到OpenOffice的启动窗口了

提示3:openoffice的大多数API指定工作参数的方式只有一种,传递一个PropertyValue数组,每一个PropertyValue就是一个Name/Value对,所以,封装一个工具类处理它是一个好主意。而且,name只是一个简单的字符串,所以校对拼写是必须做的。而value只接受Object,所以你必须做很多原始类型的封装

这种调用模式是最基本的方式,不过隐藏有很多问题:
1。种种原因,在web容器内这种直接打开程序的方式无法使用。
2。它要求在本机必须安装openoffice程序,对于C/S模式这并不是一个很好的选择

于是,我们有了第二种模式:服务模式
用过JDBC的肯定对服务模式有所认识,一个地址,一个监听,一个端口,然后所有的一切都可以通过其进行。OpenOffice提供了类似的功能

首先,我们必须把OpenOffice以后台服务方式启动,这需要这么一串参数:
-invisible -accept=socket,host=0,port=2002;urp;
invisible表示静默方式运行,
后面一串东西基本的意思就是:openoffice会在你指定的端口(这儿用的是2002)
监听用户的请求。(该字符串更具体的含义和对应功能,自行查询开发文档相关章节)

然后,我们必须更动之前获取XComp对象的代码,精确的说,我们必须更动获取XComponentContext 对象的代码。不再有BoolStap,而代之以一串更长的东西,这段东西非常的长,幸好,你只要直接copy过来就好,你可以在SDK的examples\java\ConverterServlet.java中找到这串东西,(注意,原始示例中使用的端口号不是之前我们指定的2002)

获取到Context之后,我们的代码没有变化,其他的流程一切照旧,所有的参数也一模一样。

监听模式下,还有一个附带的好处:你可以放心的把那几个jar拷贝到你需要的任何地方,而用不着非要指向OpenOffice的原始安装目录了。

欧,现在我们已经成功的让java唤醒了OpenOffice,接下来,就可以让它和java眉来眼去了。