使用Jacob开源插件操作Microsoft Word

使用Jacob开源插件操作Microsoft Word

主题

     最近项目中要进行公文的操作,所有就想到了使用java来操作word,找了一些资料,都是比较零散、杂乱的东西,今早向Google大神求救,终于发现了一位热心的国外同鞋的文章,收获颇多,因此将此文翻译出来,供大家参考,本文英语水平很烂,但是为了学习同鞋你一定要hold住。

"Am I the only person on this planet who wants to write MS Word files with Java?"
- Me, after researching Jacob, POI, WordBean and others, all to no informational avail.

难道我是这个星球上唯一的一个愿意使用java操作Microsoft Word文件的人吗?”

-我在研究完jacob,POI,WordBean和其他开源插件后发现没有好的帮助信息可以供我使用。

Jacob介绍

Jacob is a Java/COM bridge provided by Dan Adlerunder a semi GPL license (may not be used in a commercial product targetted at java developers, e.g. virtual machines, debuggers. The chance that you are not allowed to use it is very slim).

     Jacob是在半GPL许可证约束下的java/COM桥接软件,作者是Dan Adler.注:半GPL许可证是使用者不允许将软件应用于java开发的商业化软件中,比如虚拟机、调试器等。但是你不被允许使用的机会是很小的。

There is no documentation available concerning the practical use of any Microsoft applications; it is, so Adler, intended as a generic Java/COM bridge and not some MS Office API. However, M. Bigatti made a FAQ, which IMHO is not too useful when it comes to MS Word; and there is a Jacob Mailing List, where I got most of my information, even if it was tedious work.

     这里没有任何关于微软产品的实际使用的说明;因此,作者的想法是想它作为一个通用的java/COM桥组件,而不是作为一个操作word的API。然而,M. Bigatti提出了一个问题,恕我直言它对于解决word的问题是不是太有用了;并且有一个Jacob邮件列表,在哪里我得到了大部分的信息,尽管这个工作单调和乏味。

Now, this is a tutorial entirely dedicated to the handling of Microsoft Word with Jacob. If you want Excel stuff, I would rather recommend POI, hosted at the Apache Foundation; they have good excel support, but only word scratchpad stuff. If you just need to insert some unformatted text, an easier solution is the WordBean by Müller&Stein.

      现在,这是一个完全致力于使用Jacob对Word进行操作的指导材料。如果你希望使用Excel,那么我宁愿推荐你使用POI,由阿帕奇基金会维护的项目;POI由对Excel由很好的支持,但是在Word方面还有点欠缺。如果你只想插入一些没有格式的文字,那么可以使用一些简单点的解决方案,比如使用Müller&Stein编写的WordBean软件。

A good alternative to using Jacob may be Jawin, which follows exactly the same goal, namely dispatching calls to COM objects.

     还有一个Jacob的替代品是Jawin,这个遵循着与Jacob一样的目标,也是通过调用COM组件的方式调用的。

作者

This document is far from complete; I am always open for suggestions, tips and any enhancements. If you know something, please tell me. The absence of another site like this, in contrast to all the questions on JDC Search and Jacob Mailing list, imply that my page will be of some usability. My mail adress is kain at the above domain.

     这篇文档要完成还要花费一段时间;我一直是采纳大家的意见、建议和一些改进方法。如果你知道关于这个方面的东西,请告诉我。在对比了JDC搜索和Jacob邮件列表里面的所有问题后,在喜欢这个网页的情况下我的文档还是有一定的可用性的。在上述域中我的邮箱地址是Kain.

Update 2006-04: I had a nice email exchange with a guy named Jean Helou; he summarised his experiences with Jacob in a wiki documentation: it contains a section on macros, and is based on ms word xp. Also, he provided me with a link to the useful ms office object model documentation.

Update 2006-04:我与一个叫Jean Helou的家伙又一段精彩的邮件交流;他在维基百科上面总结了他对Jacob的使用经验:是在基于XP系统中的Word关于宏的使用。他还提供给我一个关于微软对象模型文档的使用连接。

Update 2006-08: A nice girl named Kathrin Eichler emailed me a section on hyperlinks; it is included below. She is using Office XP. Thanks Kathrin!

Update 2006-08:一位叫Kathrin Eichler的美女发给我了一份关于超链接使用的邮件;在下面有介绍。她使用的是xp版的office软件,感谢她。

准备工作

You need to have two files: jacob.jar and jacob.dll. You put the former in your classpath and the latter in c:\windows\system32 or your equivalent. I tested jacob both win 98 and win xp, both with ms office 97.

Then, I assume you create a new java class, make a new main(String[] asArgs)method and are at its beginning.

你需要由两个文件:jacob.jarjacob.dll。需要把jacob.jar放到你工程的classpath中并且把jacob.dll放到c:\windows\system32目录下或者其他相应的目录下。我在win98和win xp下面做过测试,两者都是使用的office97。

让我们开始吧

First, I will create some variables; you can change them almost arbitrarily. They are pretty self explaining.

首先,我需要新建一些变量;你可以按照自己的意愿随意修改。看变量的名称大体上都能知道具体的意思。

String sDir = "c:\\java\\jacob\\";
String sInputDoc = sDir + "file_in.doc";
String sOutputDoc = sDir + "file_out.doc";
String sOldText = "[label:import:1]";
String sNewText = "I am some horribly long sentence, so long that [insert bullshit here]";
boolean tVisible = true;
boolean tSaveOnExit = false;

sOldText holds the label that I will search and replace. tVisible is only true for debugging purposes, to see whats going on. tSaveOnExitis false since I save explicitly.

sOldText表示我要进行搜索和替换的文本。tVisible只有在调试的时候才设置为true,这样你可以看见具体的操作过程。tSaveOnExit为false直到我明确的进行保存操作。

Now, we will open word and read the document as well as some base variables.

现在,我们将打开word并且根据上面定义的基础变量来读取文档的内容。

    ActiveXComponent oWord = new ActiveXComponent("Word.Application");
    oWord.setProperty("Visible", new Variant(tVisible));
    Object oDocuments = oWord.getProperty("Documents").toDispatch();
    Object oDocument = Dispatch.call(oDocuments, "Open", sInputDoc).toDispatch();
    Object oSelection = oWord.getProperty("Selection").toDispatch();
    Object oFind = oWord.call(oSelection, "Find").toDispatch();

Run this. It should open word, but dont do something cool.

执行上面代码,将会打开一个word,但是上面也不做。

oDocuments holds the list of documents. oDocument holds our specific document file_in.doc. oSelection and oFindare objects we need for the next step, selecting and inserting.

oDocuments保存了文档的列表(因为是多文档应用程序)。oDocument被认为是指定的文件file_in.doc. oSelectionoFind是我们要进行下一步操作的对象,主要用来进行搜索和插入操作。

 Dispatch.put(oFind, "Text", sOldText);
    Dispatch.call(oFind, "Execute");
    Dispatch.put(oSelection, "Text", sNewText);

Now we search for sOldText, execute the search (which results in the label being selected inside Word), and replace that selection with the new text (which, in turn, is also selected).

现在我们搜索sOldText内容,执行搜索语句,并且使用新的文本替代选中的项目。

So next, we leave that select stuff.

因此下一步,我们离开选择的东西。

Dispatch.call(oSelection, "MoveDown");
Dispatch.put(oSelection, "Text", "\nSo we got the next line including BR.\n");

We move the cursor down, effectively leaving the selection (yes, it works just like a VB macro inside Word; works also with MoveUp, MoveLeft, MoveRight). Then, we insert other text.

我们将光标向下移动,有效的离开选中的项目,然后开始插入其他文本。(它工作起来类似于嵌入到word中的VB宏;使用起来有MoveUp, MoveLeft, MoveRight功能)

Now we want to format text. Since we always operate with selected text (the whole "TypeText" directive mentioned at the mailing list didnt quite work for me), we make the format afterwards (unto the selected text, not unto the next-to-be-typed text).

现在我们希望格式化文本。我们一直采用的方式是先选中文本,然后进行下一步操作,下面是具体的使用方法。

Object oFont = Dispatch.get(oSelection, "Font").toDispatch();
    Dispatch.put(oFont, "Bold", "1");
    Dispatch.put(oFont, "Italic", "1");
    Dispatch.put(oFont, "Underline", "0");

Now the selected text (the "\nSo we got ... BR.\n") is both bold and italic.

Object oAlign = Dispatch.get(oSelection, "ParagraphFormat").toDispatch();
    Dispatch.put(oAlign, "Alignment", "3");

And now the alignment is block (0 - Left, 1 - Center, 2 - Right, 3 - Block; at least I hope so ;-). For now, this is the minimal thing that can be useful for you. Using the MoveDown and Textdirectives you can do the basics.

现在对其是按照快的方式的(0代表左对齐,1是居中,2是右对齐,3是快对齐)。现在这是对你有所帮助而要做的最少的事情,使用MoveDown和Text直接做你想做的事情。

保存和关闭

Well, there were a lot of suggestions on the mailing list, but that one worked for me.

在Jacob邮件列表里面有好多关于保存和关于的建议,但是这个是我使用的。

 Object oWordBasic = Dispatch.call(oWord, "WordBasic").getDispatch();
    Dispatch.call(oWordBasic, "FileSaveAs", sOutputDoc);

Dont ask me why. It just works.

不要问我为什么,它确实是有效的。

Dispatch.call(oDocument, "Close", new Variant(tSaveOnExit));
    oWord.invoke("Quit", new Variant[0]);

This is straigthforward. No sweat.

插入图片

Yes its possible to embed images pretty easy.

使用Jacob来插入图片是件很容易的事情。

 String sImgFile = sDir + "image.png";
    Dispatch.call(oSelection, "MoveDown");
    Object oImage = Dispatch.get(oSelection, "InLineShapes").toDispatch();
    Dispatch.call(oImage, "AddPicture", sImgFile);

Well, it just works the way shown by the mailing list. Dont ask me about the image format (text flow and such) though. Better, if you know it, mail me.

超链接的使用

Hyperlinks are also pretty straightforward (courtesy Kathrin Eichler, under Office XP):

超链接也可以非常完美的直接使用。

String sHyperlink = "http://www.google.com";
    Dispatch.put(oSelection, "Text", "Text for the link to Google");
    Object oRange = Dispatch.call(oSelection, "Range");
    Object oLink = Dispatch.get(oDocument, "Hyperlinks").toDispatch();
    Dispatch.call(oLink, "Add", oRange, sHyperlink);

I have not tried that personally yet (under Office 97), so your mileage may vary.

表格

Holy slimily, I got no idea yet. Am researching VB code and stuff. I got some suggestions from the mailing list how to add a row to a table and how to navigate a table, but creating... Well, still to come.

到现在都没有什么好的注意。我研究了VB代码和其工作原理。我从邮件列表那里得到了一些建议,怎么去添加一行和越过一个表格,但是对于创建操作。。。。还是需要进一步研究啊。

列表/枚举

The VB code looks like shit. I have no idea how to work here. Still to come.

VB代码看起来像一坨屎。到现在都没有号的想法去实现怎么操作,还需要努力。

总结

上面是一个国外友人的文章,主要介绍了Jacob的使用方法,希望对有志于使用Java操作Word的童鞋有所帮助。

posted @ 2011-10-28 10:50  Rush_SONG  阅读(11316)  评论(1编辑  收藏  举报