天天看點

Java利用COM元件實作Excel轉換為HTML檔案或PDF文檔

業務需求如下:

      1.将使用者上傳的Excel轉換為HTML進行頁面展示(Excel文檔格式随意)

      2.将使用者上傳的Excel轉換為PDF提供下載下傳(不能換頁,隻能顯示在一張PDF上面)

針對以上需求你可能會問,操作office文檔為什麼不使用POI?

       答:因為操作非常麻煩。(除非你把Excel格式定下來且不需要樣式)

       其實通過需求發現,這不就是office軟體的“另存為”功能嘛?對不對?那麼有沒有什麼可以直接調用office軟體現成的“另存為”功能呢?還真有。那就是office的com元件。經過一番搜尋,發現Java可以使用jacob來實作com元件的調用。一瞬間功能就變得異常簡單。什麼?你不知道什麼是com元件?問度娘就好啦。這裡就不解釋了。

       雖然網上已經有很多類似的文章,畢竟jacob已經是很久遠的項目了。汗。但大多數文章都很單一,就隻是告訴你最最基本的實作。啥也不說。想定制一下完全不知道怎麼弄,裡面使用的常量也不知道是哪裡來的(PS:代碼會給出官方API)。是以才有了這篇文章。一是自己用。二是告訴有需求的你。

 使用COM元件有一定的限制,請注意:

        1.伺服器必須是windows系統,且安裝office軟體。(PS:軟體都沒有怎麼調用它的功能呢?)

        2.jacob不同的版本需要對應不同的jdk版本,否則JVM會直接崩潰。具體情況自己試

           jacob下載下傳位址:https://sourceforge.net/projects/jacob-project/

           dll檔案可放在項目根目錄或JDK的bin目錄或Windows\System32或Windows\SysWOW64目标或tomcat/bin目錄

作者的開發環境如下:

        伺服器是:server2008

        office版本:office2007

        開發環境是:JDK1.8

        jacob版本是:1.9

代碼實作如下:具體調用參數可參考microsoft的官網,雖然是vba的 - - !

官方API:https://docs.microsoft.com/zh-cn/office/vba/api/overview/excel/object-model

import  com.jacob.activeX.ActiveXComponent;					
import  com.jacob.com.Dispatch;					
import  com.jacob.com.Variant;					
					
/**					
 * @author Code菜鳥 (qq:969422014)					
 **/					
public class JacobUtil					
{					
    //常量定義API:https://docs.microsoft.com/zh-cn/office/vba/api/excel.xlfileformat				
    public static final int EXCEL_HTML = 44;					
    public static final int EXCEL_PDF = 57;					
    					
    public static void main(String [] args)					
    {					
    	excelToPdf("D:\\1.xlsx","D:\\1.pdf");				
    }					
    					
    /**					
     * EXCEL轉pdf					
     * @param xlsfile EXCEL檔案全路徑					
     * @param pdffile 轉換後pdf存放路徑					
     */					
    public static void excelToPdf(String xlsfile, String pdffile) {					
        // 啟動excel					
        ActiveXComponent app = new ActiveXComponent("Excel.Application");					
        try {					
	          // 設定excel不可見				
	          app.setProperty("Visible", new Variant(false));				
	          // 禁用宏				
	          app.setProperty("AutomationSecurity", new Variant(3));				
	          // 得到工作表				
	          Dispatch excels = app.getProperty("Workbooks").toDispatch();				
	          // 打開excel檔案				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.workbooks.open				
	  		  Dispatch excel = Dispatch.invoke(excels,"Open",Dispatch.Method,new Object[] {		
	  				xlsfile,
	  				new Variant(false),
	  				new Variant(false)
	  		  },new int[9]).toDispatch();		
	          // 擷取excel表中的sheet集合				
	  		  // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.worksheets		
	          Dispatch sheets = Dispatch.call(excel, "Worksheets").toDispatch();				
	          // 擷取sheet集合中的第一個sheet				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.worksheets.item				
	          Dispatch sheet = Dispatch.call(sheets, "Item", new Integer(1)).toDispatch();				
	          // 擷取第一個sheet的頁面設定對象				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.pagesetup				
	          Dispatch pageSetup = Dispatch.call(sheet, "PageSetup").toDispatch();				
	          // 将excel表格 設定成A3的大小				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.pagesetup.papersize				
	          Dispatch.put(pageSetup, "PaperSize", new Integer(8));//A3是8,A4是9,A5是11等等				
	          // 縮放值為100或false				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.pagesetup.zoom				
	          Dispatch.put(pageSetup, "Zoom", false);				
	          // 所有列為一頁(1或false)				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.pagesetup.fittopageswide				
	          Dispatch.put(pageSetup, "FitToPagesWide", 1);				
	          // 設定上邊距				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.pagesetup.topmargin				
	          Dispatch.put(pageSetup, "TopMargin", 0);				
	          // 設定右邊距				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.pagesetup.rightmargin				
	          Dispatch.put(pageSetup, "RightMargin", 0);				
	          // 設定左邊距				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.pagesetup.leftmargin				
	          Dispatch.put(pageSetup, "LeftMargin", 0);				
	          // 作為pdf格式儲存到臨時檔案				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.workbook.exportasfixedformat				
	  		  Dispatch.invoke(excel,"ExportAsFixedFormat",Dispatch.Method,new Object[]{		
	  				new Variant(0), // PDF格式=0 常量描述:https://docs.microsoft.com/zh-cn/office/vba/api/excel.xlfixedformattype
	  				pdffile,
	  				new Variant(0)  // 0=标準 (生成的PDF圖檔不會變模糊) 1=最小檔案 (生成的PDF圖檔糊的一塌糊塗)
	  		  },new int[1]);		
	  		  // 關閉excel		
	          Dispatch.call(excel, "Close", new Variant(false));				
        } catch (Exception e) {					
            e.printStackTrace();					
        } finally {					
        	// 關閉excel程式				
            app.invoke("Quit", new Variant[] {});					
        }					
    }					
    					
    /**					
     * EXCEL轉HTML					
     * @param xlsfile EXCEL檔案全路徑					
     * @param htmlfile 轉換後HTML存放路徑					
     */					
    public static void excelToHtml(String xlsfile, String htmlfile) {					
        // 啟動excel					
        ActiveXComponent app = new ActiveXComponent("Excel.Application");					
        try {					
	          // 設定excel不可見				
	          app.setProperty("Visible", new Variant(false));				
	          Dispatch excels = app.getProperty("Workbooks").toDispatch();				
	          // 打開excel檔案				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.workbooks.open				
	          Dispatch excel = Dispatch.invoke(				
	                    excels,				
	                    "Open",				
	                    Dispatch.Method,				
	                    new Object[] { xlsfile, new Variant(false),				
	                            new Variant(true) }, new int[1]).toDispatch();				
	          // 作為html格式儲存到臨時檔案				
	          // API資料:https://docs.microsoft.com/zh-cn/office/vba/api/excel.workbook.saveas				
	          Dispatch.invoke(excel, "SaveAs", Dispatch.Method, new Object[] {				
	                    htmlfile,				
	                    new Variant(EXCEL_HTML) // 類型常量:https://docs.microsoft.com/zh-cn/office/vba/api/excel.xlfileformat				
	          }, new int[1]);				
	          Variant f = new Variant(false);				
	          // 關閉excel文檔				
	          Dispatch.call(excel, "Close", f);				
        } catch (Exception e) {					
            e.printStackTrace();					
        } finally {					
        	// 退出excel程式				
            app.invoke("Quit", new Variant[] {});					
        }					
    }					
}					
           

其它需求,請參閱:https://docs.microsoft.com/zh-cn/office/vba/api/excel.xlfileformat

然後修改以下代碼即可:

Dispatch.invoke(excel, "SaveAs", Dispatch.Method, new Object[] {

      htmlfile,

      new Variant(EXCEL_HTML) // 這裡改需要的常量

}, new int[1]);