標籤:
1、介紹
Jacob 是Java-COM Bridge的縮寫,它在Java與微軟的COM組件之間構建一座橋樑。使用Jacob內建的DLL動態連結程式庫,並通過JNI的方式實現了在Java平台上對COM程式的調用。至於什麼是COM組件,大家自己Google吧。
2、安裝和配置
Jacob是一個開源軟體,它的官方網站是:http://danadler.com/jacob/ 大家可以到上面下載原始碼研究,也可以直接下載編譯後的二進位檔案。
下載包jacob_x.x.zip,解壓後有幾個檔案:jacob.jar、jacob-x.x-M2-x86.dll
把jacob-x.x-M2-x86.dll拷貝到%JAVA_HOME% 下的 bin 目錄下,其中,%JAVA_HOME%就是JDK的安裝目錄。接著直接在java IDE中引用jacob.jar就可以使用了。
3、轉換word為pdf、html、txt 的樣本
package com.shanhy.demo.windowsoffice;import java.io.File;import com.jacob.activeX.ActiveXComponent;import com.jacob.com.ComThread;import com.jacob.com.Dispatch;import com.jacob.com.Variant;/** * * 將jacob.dll放入JDK的bin目錄下 * 把jacob.jar放入項目的buildPath中(web項目放到WEB-INF\lib目錄下) * * @author 單紅宇 * */public class ConvertToPdf {// WORD 轉換文檔格式參數值:17為pdf,8為html,2為txt(支援的格式不限與此,其他格式暫為列出)static final int wdFormatPDF = 17;// PDF 格式static final int wdFormatHTML = 8;// HTML 格式static final int wdFormatTXT = 2;// TXT 格式/** * Word文檔轉換 * * @param fromfileName * @param toFileName * @author SHANHY */public void wordConvert(String fromfileName, String toFileName) {System.out.println("啟動Word...");ComThread.InitSTA(); long start = System.currentTimeMillis();ActiveXComponent app = null;Dispatch doc = null;try {app = new ActiveXComponent("Word.Application");//建立一個word對象app.setProperty("Visible", new Variant(false)); //不可見開啟wordapp.setProperty("AutomationSecurity", new Variant(3)); //禁用宏Dispatch docs = app.getProperty("Documents").toDispatch();//擷取文擋屬性System.out.println("開啟文檔 >>> " + fromfileName);//Object[]第三個參數是表示“是否唯讀方式開啟”doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { fromfileName, new Variant(false), new Variant(true) }, new int[1]).toDispatch();File tofile = new File(toFileName);if (tofile.exists()) {tofile.delete();}int formatValue = -1;if(toFileName.toLowerCase().endsWith(".pdf")){formatValue = wdFormatPDF;}else if(toFileName.toLowerCase().endsWith(".html")){formatValue = wdFormatHTML;}else if(toFileName.toLowerCase().endsWith(".txt")){formatValue = wdFormatTXT;}else{formatValue = -1;}if(formatValue != -1){System.out.println("轉換文檔 ["+fromfileName+"] >>> ["+toFileName+"]"); Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { toFileName, new Variant(formatValue) }, new int[1]);}else{System.out.println("轉換檔到目的文件不被支援!["+fromfileName+"] >>> ["+toFileName+"]"); }long end = System.currentTimeMillis();System.out.println("用時:" + (end - start) + "ms.");} catch (Exception e) {e.printStackTrace();System.out.println("========Error:文檔轉換失敗:" + e.getMessage());} finally {Dispatch.call(doc, "Close", false);System.out.println("關閉文檔");if (app != null)app.invoke("Quit", new Variant[] {});}// 如果沒有這句話,winword.exe進程將不會關閉ComThread.Release(); ComThread.quitMainSTA(); }/** * PPT(PowerPoint)文檔轉換 * * @param fromfileName * @param toFileName * @author SHANHY */public void pptConvert(String fromfileName, String toFileName) {System.out.println("啟動PPT...");ComThread.InitSTA(); long start = System.currentTimeMillis();ActiveXComponent app = null;Dispatch doc = null;try {app = new ActiveXComponent("Word.Application");//建立一個word對象app.setProperty("Visible", new Variant(false)); //不可見開啟wordapp.setProperty("AutomationSecurity", new Variant(3)); //禁用宏Dispatch docs = app.getProperty("Documents").toDispatch();//擷取文擋屬性System.out.println("開啟文檔 >>> " + fromfileName);//Object[]第三個參數是表示“是否唯讀方式開啟”doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { fromfileName, new Variant(false), new Variant(true) }, new int[1]).toDispatch();File tofile = new File(toFileName);if (tofile.exists()) {tofile.delete();}int formatValue = -1;if(toFileName.toLowerCase().endsWith(".pdf")){formatValue = wdFormatPDF;}else if(toFileName.toLowerCase().endsWith(".html")){formatValue = wdFormatHTML;}else if(toFileName.toLowerCase().endsWith(".txt")){formatValue = wdFormatTXT;}else{formatValue = -1;}if(formatValue != -1){System.out.println("轉換文檔 ["+fromfileName+"] >>> ["+toFileName+"]"); Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { toFileName, new Variant(formatValue) }, new int[1]);}else{System.out.println("轉換檔到目的文件不被支援!["+fromfileName+"] >>> ["+toFileName+"]"); }long end = System.currentTimeMillis();System.out.println("用時:" + (end - start) + "ms.");} catch (Exception e) {e.printStackTrace();System.out.println("========Error:文檔轉換失敗:" + e.getMessage());} finally {Dispatch.call(doc, "Close", false);System.out.println("關閉文檔");if (app != null)app.invoke("Quit", new Variant[] {});}// 如果沒有這句話,winword.exe進程將不會關閉ComThread.Release(); ComThread.quitMainSTA(); }public static void main(String[] args) {ConvertToPdf d = new ConvertToPdf();d.wordConvert("g:\\test.docx", "g:\\test.pdf");}}
讀、寫Word的簡單樣本
import com.jacob.activeX.ActiveXComponent; import com.jacob.com.Variant; import com.jacob.com.Dispatch; public class Word { String strDir = "c:jacob_1.9"; String strInputDoc = strDir + "file_in.doc"; String strOutputDoc = strDir + "file_out.doc"; String strOldText = "[label:import:1]"; String strNewText = "I am some horribly long sentence, so long that [insert anything]"; boolean isVisible = true; boolean isSaveOnExit = true; public Word() { ActiveXComponent oWord = new ActiveXComponent("Word.Application"); oWord.setProperty("Visible", new Variant(isVisible)); Dispatch oDocuments = oWord.getProperty("Documents").toDispatch(); Dispatch oDocument = Dispatch.call(oDocuments, "Open", strInputDoc). toDispatch(); Dispatch oSelection = oWord.getProperty("Selection").toDispatch(); Dispatch oFind = oWord.call(oSelection, "Find").toDispatch(); Dispatch.put(oFind, "Text", strOldText); Dispatch.call(oFind, "Execute"); Dispatch.put(oSelection, "Text", strNewText); Dispatch.call(oSelection, "MoveDown"); Dispatch.put(oSelection, "Text", "nSo we got the next line including BR.n"); Dispatch oFont = Dispatch.get(oSelection, "Font").toDispatch(); Dispatch.put(oFont, "Bold", "1"); Dispatch.put(oFont, "Italic", "1"); Dispatch.put(oFont, "Underline", "0"); Dispatch oAlign = Dispatch.get(oSelection, "ParagraphFormat"). toDispatch(); Dispatch.put(oAlign, "Alignment", "3"); Dispatch oWordBasic = (Dispatch) Dispatch.call(oWord, "WordBasic"). getDispatch(); Dispatch.call(oWordBasic, "FileSaveAs", strOutputDoc); Dispatch.call(oDocument, "Close", new Variant(isSaveOnExit)); oWord.invoke("Quit", new Variant[0]); } public static void main(String[] args) { Word word = new Word(); } }
4、jacob.jar的結構
jacob包括兩個部分:
com.jacob.activeX: ActiveXComponent類
com.jacob.com: 其它類和元素
5、Jacob類
Jacob的結構很簡單,包含以下幾個類:
ActiveXComponent Class:封裝了Dispatch對象,用於建立一個封裝了COM組件對象的Java Object
Dispatch Class:用於指向封裝後的MS資料結構。常用的方法有call,subcall,get,invoke…後面會介紹使用方法。
Variant Class:用於映射COM的Variant資料類型。提供Java和COM的資料交換。
ComException Class:異常類
6、Jacob方法
用於訪問COM/DLL對象的方法,讀取、修改COM/DLL對象的屬性。
call method:屬於Dispatch類。用於訪問COM/DLL對象的方法。方法進行了重載,方便不同場合調用。返回一個Variant類型的值。
callSub method:使用方法和call一樣,不過它不傳回值。
get method:讀取COM對象的屬性值,返回一個Variant類型值。
put method:設定COM對象的屬性值。
invoke method:call的另一種用法,更複雜一些。
invokesub method:subcall的另一種用法
getProperty method:屬於ActiveXComponent類,讀取屬性值,返回一個Variant類型值。
setProperty method:屬於ActiveXComponent類,設定屬性值。
要注意一點:在使用Jacob時,很重要的一點是,使用者必須安裝有Office的應用程式。否則也就無法建立Java-COM橋,進而無法解析了。
部分內容參考: http://www.cnblogs.com/vulcans/archive/2009/09/08/1562588.html
使用jacob調用Windows的com對象,轉換Office檔案為pdf、html等