2014年5月19日 星期一

Coldfusion直接讀取/產生Excel檔案 (使用POI元件)

最近在 Ben Nadel 先生的網站發現他有個Component計畫,他利用 apache.org 的 poi project 來製作一個可以讀寫 EXCEL 檔案的 Component,操作 EXCEL 檔真的蠻方便的。而且 poi project 以處理 office文件為目標,算是很棒的專案。

正在想如何直接透過 Coldfusion 網頁處理客戶的 Excel 檔案時,這真是一大幫助啊!

請先參考相關連結:

apache.org 的 poi 計畫 apache poi jar下載

Ben Nadel 的 POIUtility 文章出處Ben Nadel 的 POIUtility 專案

我的環境
本人使用 Railo 3.3.4.003 執行 Coldfusion ,所以核心是 Apache 比較沒有問題,至於Adobe的Coldfusion可能要再研究一下 Ben Nadel 的專案了。

1、下載  JAR 檔案
注意下載的 poi jar 版本,由於我使用的 Railo 3.3.4.003版本無法搭配最新的 poi,所以測試到使用 poi-3.0-FINAL.jar 是沒有問題的,太新的反而不能用。

把下載的 jar 放在 Railo Server 路徑下的 \lib\ext 裡面,重新啟動服務即完成掛載。

2、下載 Ben Nedal 的 POIUtility.cfc

假設網頁運行路徑在 \webroot\
你可接放在 \webroot\
而我的測試是放在 \webroot\COM 裡面 (我個人習慣Component都是放在COM路徑下)

3-1、測試一:讀取全部
首先,建立一個 Excel 檔案 "測試活頁簿.xls",裡面有3個Sheet




3-1.1、寫一段讀取用的 script:
<!--- 建立並初始化POI物件 --->
<cfset POIobj = CreateObject("component","COM.POIUtility").Init() >

<!--- 取得我要測試的Excel檔案路徑. --->
<cfset myFile = ExpandPath( "./測試活頁簿.xls" ) >

<!--- 測試一:透過POI物件讀取Excel檔案,並指定此excel檔案有標題列(第一行) --->
<cfset myExcel = POIobj.ReadExcel(FilePath = myFile,HasHeaderRow = true) >

<!--- 傾印出內容 --->
<cfdump var="#myExcel#">

3-1.2、顯示結果:




3-2、測試二:單獨讀取檔案中第二個Sheet資料
利用3-1的EXCEL檔案

3-2.1、寫一段讀取用的 script:
<!--- 建立並初始化POI物件 --->
<cfset POIobj = CreateObject("component","COM.POIUtility").Init() >

<!--- 取得我要測試的Excel檔案路徑. --->
<cfset myFile = ExpandPath( "./測試活頁簿.xls" ) >

<!---測試二:透過POI物件讀取Excel檔案,指定此excel檔案有標題列,並指定讀取第二Sheet表
(SheetIndex索引從0開始) --->
<cfset mySheet = POIobj.ReadExcel(FilePath = myFile,HasHeaderRow = true,SheetIndex = 1) >

<!--- 傾印出內容 --->
<cfdump var="#mySheet#">

3-2.2、顯示結果:



4、寫入測試:把3-1讀取出的檔案寫到另一個檔案去
<!--- 建立並初始化POI物件 --->
<cfset POIobj = CreateObject("component","COM.POIUtility").Init() >

<!--- 取得我要測試的Excel檔案路徑. --->
<cfset myFile = ExpandPath( "./測試活頁簿.xls" ) >

<!--- 測試一:透過POI物件讀取Excel檔案,並指定此excel檔案有標題列(第一行) --->
<cfset myExcel = POIobj.ReadExcel(FilePath = myFile,HasHeaderRow = true) >

<!--- 建立一個儲存用的陣列 --->
<cfset mySheets = ArrayNew( 1 ) >

<!--- 利用POI元件建立Sheet結構,再將讀取的Excel檔案,逐個Sheet填入,
並且重新變更Sheet名稱,與欄位名稱,
這裡要注意的是,Query陣列起始是1不是0(呼叫底層Java元件才要用0)--->
<cfset mySheets[ 1 ] = POIobj.GetNewSheetStruct() >
<cfset mySheets[ 1 ].Query = myExcel[ 1 ].Query >
<cfset mySheets[ 1 ].SheetName = "材料" >
<cfset mySheets[ 1 ].ColumnList = "column1,column2,column3" >
<cfset mySheets[ 1 ].ColumnNames = "料別,菜式,費用" >

<!--- 設定第二Sheet --->
<cfset mySheets[ 2 ] = POIobj.GetNewSheetStruct() >
<cfset mySheets[ 2 ].Query = myExcel[ 2 ].Query >
<cfset mySheets[ 2 ].SheetName = "廚師團" >
<cfset mySheets[ 2 ].ColumnList = "column1,column2,column3,column4" >
<cfset mySheets[ 2 ].ColumnNames = "name,gender,job,payments" >

<!--- 設定第三Sheet --->
<cfset mySheets[ 3 ] = POIobj.GetNewSheetStruct() >
<cfset mySheets[ 3 ].Query = myExcel[ 3 ].Query >
<cfset mySheets[ 3 ].SheetName = "月收入" >
<cfset mySheets[ 3 ].ColumnList = "column1,column2,column3,column4" >
<cfset mySheets[ 3 ].ColumnNames = "month,desk,套餐,營收" >

<!--- 把新作陣列(POI結構化)存到新的Excel檔案去 --->
<cfset POIobj.WriteExcel(FilePath = ExpandPath("./新活頁簿.xls"),Sheets = mySheets) >

4.1、輸出檔案結果:





整個測試結果都很正常,表示這些元件都可用,這下終於可以好好處理客戶的 EXCEL 了。


0 個回應: