jacob操作office分享
jacob(java com bridge,java com橋)分為兩個部分,jacob.jar,jacob.dll,使用時兩個東西的版本要一致,而且還分32位和64位,它的位數和jdk的位數有關,與操作系統的位數無關。它的原理是通過java的jni功能,調用系統組件dll,通過這個com橋來操作com組件(windows的一種軟件編程技術吧),最終完成對office文檔的操作。
環境配置:
1、在工程中引入jar包
2、將dll文件放在jdk的path目錄下面,通過System.getProperty("java.library.path");可以看到path路徑,或者直接放到jdk/bin、jre/bin、system32/system64下面都放一份,總能找得到,版本要急著對應好。
3、附件為我使用的組件,好像是1.17版本,配合64位jdk使用。
常用類以及方法
ComThread:com組件管理,用來初始化com線程,釋放線程,所以會在操作office之前使用,操作完成再使用。
ActiveXComponent:創建office的一個應用,比如你操作的是word還是excel
Dispatch:調度處理類,封裝了一些操作來操作office,里面所有的可操作對象基本都是這種類型,所以jacob是一種鏈式操作模式,就像StringBuilder對象,調用append()方法之后返回的還是StringBuilder對象
Variant:封裝參數數據類型,因為操作office是的一些方法參數,可能是字符串類型,可能是數字類型,雖然都是1,但是不能通過,可以通過Variant來進行轉換通用的參數類型,new Variant(1),new Variant("1"),
Dispatch的幾種靜態方法:這些方法就是要用來操作office的。
?call( )方法:調用COM對象的方法,返回Variant類型值。
?invoke( )方法:和call方法作用相同,但是不返回值。
?get( )方法:獲取COM對象屬性,返回variant類型值。
?put( )方法:設置COM對象屬性。
以上方法中有的有很多重載方法,調用不同的方法時需要放置不同的參數,至于哪些參數代表什么意思,具體放什么值,就需要參考vba代碼了,僅靠jacob是無法進行變成的。
Variant對象的toDispatch()方法:將以上方法返回的Variant類型轉換為Dispatch,進行下一次鏈式操作。
結合vba來進行一些操作的解讀(以word為例,excel基本上差不多)
jacob操作office網上也有很多教程,比如打開文檔,保存,插入圖片之類的,看了那些,也只能會這幾種操作,jacob文檔中也不會有那種操作參數是什么,現在我結合vba代碼分享一下我的理解,有什么新的操作就可以自己來完成。
1、初始化com線程
使用jacob之前使用下面的語句來初始化com線程,大概意思是打開冰箱門,準備放大象。。。
使用完成后使用下面的語句來關閉現場,大概意思是關上冰箱門。。。
2、創建應用程序對象,設置參數,得到文檔集合
操作一個文檔之前,我們必須要創建一個應用對應,比如是word還是excel,設置一些文檔應用的參數,得到文檔集合對象,(大家應該知道word是Documents,excel是WorkBooks)
ActiveXComponent wordApp = new ActiveXComponent("Word.Application");//word ActiveXComponent wordApp = new ActiveXComponent("Excel.Application");//excel wordApp.setProperty("Visible", new Variant(false));//設置應用操作是文檔不在明面上顯示,只在后臺靜默處理。
這個操作就是模仿vba的寫法,Application.Visible = False;vba代碼中的對application的設置這里都可以用
獲得文檔集合,用來操作我們需要處理的文檔,
Dispatch document = wordApp.getProperty("Documents").toDispatch();
vba寫法Application.Documents,C#的寫法:new Microsoft.Office.Interop.Word.Application().Documents
可以看出來基本相似,如果對c#比較熟悉的話,可以直接從c#中翻譯過來,不熟悉的話可以直接網上查vba代碼,進行翻譯。
3、打開文檔
有了文檔對象集合,我們就可以來操作文檔了,鏈式操作就此開始:
call方法,調用open方法,傳遞一個參數,返回一個我們的word文檔對象, Dispatch doc = Dispatch.call(document, "Open",new Variant("D:\\my.doc")).toDispatch();
同樣從vba代碼翻譯過來,很多vba代碼我們可以在word文檔中自己找到,
從vba代碼中可以看到documents的open方法打開了一個文檔,第一個參數就是文檔的路徑,后面的參數大家可以自己去研究,參數多的有多參數的方法,還有數據參數的方法,都可以用來調用。
現在打開了一個文檔,我們可以進行操作了。
4、操作文檔,每頁插入一個圖片,并調整大小和位置
我錄制一個宏插入圖片,翻到下一頁,再插入一個圖片,查看vba代碼如下:
其中里面的Selection代表當前光標位置或者所選范圍,官方解釋如下:
該對象代表窗口或窗格中的當前所選內容。所選內容代表文檔中被選定(或突出顯示的)的區域,若文檔中沒有所選內容,則代表插入點。每個文檔窗格只能有一個活動的 Selection對象,并且整個應用程序中只能有一個活動的 Selection對象。
翻譯為java代碼為:
for(int i = 0; i < 2;i++){ Dispatch selection = Dispatch.get(wordApp, "Selection").toDispatch(); Dispatch inLineShapes = Dispatch.get(selection, "InLineShapes").toDispatch(); Dispatch picture = Dispatch.call(inLineShapes, "AddPicture", imgPath).toDispatch(); //選中圖片 Dispatch.call(picture, "Select"); //設置寬度高度 Dispatch.put(picture, "Width", new Variant(10)); Dispatch.put(picture, "Height", new Variant(10)); //設置圖片相對左上角偏移位置 selection = Dispatch.get(wordApp, "Selection").toDispatch(); Dispatch shapeRange = Dispatch.get(selection, "ShapeRange").toDispatch(); Dispatch.put(shapeRange, "Left", new Variant(left)); Dispatch.put(shapeRange, "Top", new Variant(top)); //翻到下一頁 Dispatch browser = Dispatch.get(wordApp, "Browser").toDispatch(); Dispatch.call(browser, "Next"); }
從上面的代碼可以看出,每一行代碼獲取一個對象,相應于vba的用“.”點出來的一個對象,大概意思就是得到選中位置,得到圖形范圍,插入圖片,選中圖片,設置寬高,設置相對當前頁的左邊距,上邊距,然后將Application.Browser.Next翻譯為最后兩行代碼,翻到下一頁,繼續插入圖片進行處理。
這里是固定的頁碼,如果我們不知道文檔的頁碼呢,請看下一個案例。
5、得到word文檔的頁碼:
網上找到一段獲取文檔頁數的VBA代碼Selection.Information(wdNumberOfPagesInDocument),按照我們的理解,翻譯為java代碼為:
Dispatch selection = Dispatch.get(wordApp, "Selection").toDispatch(); //如果調用方法或者屬性要得到某個值的話,直接tostring或者別的就可以了 pages = Dispatch.call(selection, "Information",new Variant(4)).toString();
調用selection的Information方法,傳入一個參數可以看到,參數中我寫的是4,哪里來的呢?
vba中的wdNumberOfPagesInDocument,我們不知道是什么,肯定是一個常量,都說在msdn上能找到,我是找不到,我有個辦法,
打開我們word中的vba編輯器,吧vba代碼貼到我們錄制的宏的第一行,左邊添加一個端點,運行一下,
這樣就可以看到常量值了,是4,寫上就行可,可以得到頁碼的結果,另外還有一種獲得頁數的方法:
ActiveDocument.BuiltInDocumentProperties(wdPropertyPages)
比葫蘆畫瓢,翻譯為java代碼為
Dispatch activeDocument = Dispatch.get(wordApp, "ActiveDocument").toDispatch(); pages = Dispatch.call(activeDocument, "BuiltInDocumentProperties",new Variant(14)).toString();
通過wordApp獲取ActiveDocument對象,調用它的BuiltInDocumentProperties方法,傳入一個參數wdPropertyPages的值是14,而上面的還有另外一種寫法,官方解釋說以下兩行代碼意思一樣,所以還可以翻譯為另一種寫法
BuiltinDocumentProperties.Item(1)
BuiltinDocumentProperties(1)
先獲取BuiltinDocumentProperties對象,再調用Item方法 Dispatch activeDocument = Dispatch.get(wordApp, "ActiveDocument").toDispatch(); Dispatch builtInDocumentProperties = Dispatch.get(activeDocument, "BuiltInDocumentProperties").toDispatch(); pages = Dispatch.call(builtInDocumentProperties, "Item",new Variant(14)).toString();
6、保存文檔
Dispatch.call(doc, "Save");
doc是我們打開的文檔的對象
7、退出wordapplication
參數有很多個,我們一個都不傳,執行完后winword進程關閉 wordApp.invoke("Quit", new Variant[] {});
8、釋放com線程
ComThread.Release();
結束
??? 以上是兩個小案例還分享一下我個人的心得,個人感覺jacob還是很好用的,只不過有時候有的對象不知道怎么獲取,只能一點一點的嘗試,比如selection,activeDocument,錄制宏也看不到是怎么來的,最終發現都是wordapplication來的,所以宏里面開始的東西如果找不到都可以從application里面去找的。
歡迎大家共同研究,如有不正確的地方歡迎指正。
原文鏈接:http://men4661273.iteye.com/blog/2097871
總結
以上是生活随笔為你收集整理的jacob操作office分享的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不脱壳照样破解MyVideoConver
- 下一篇: js成长之路