2008-04-18

[PHP] Excel檔案轉入的方式

依然是專案管理系統的功能。因為之前Excel檔案的匯入是採用另存新檔後的csv匯入;因為以PHP來說,xls的Excel檔內含太多不可確定的格式,不如單純的逗號分隔檔案csv的資料來的純粹。不過站在使用者的角度,「另存新檔」本身就是一個多餘的動作,何況再轉存成csv檔後並不是直接按確定這麼簡單;因為Excel檔案格式的改變,所以會有M$貼心的提醒...總之最後導致整個匯入動作感覺很不友善。

儘管PTT PHP版一面倒的建議採用csv檔作資料的讀入處理,但是使用者才不管你這麼多勒!對使用者友善,就是對程式設計者的殘忍啊...然而,之所以會需要程式設計者,也是為了要對使用者更友善啊~所以,我找了一下網路上直接上傳Excel檔轉入資料的方法,目前找到二種試驗後都成功的方法:

第一種是利用PHP的COM()函數,呼叫PHP所在Server的M$ Office程式做處理。這個函數運用的感覺比較像是在寫bat檔,利用一連串指令在使用者不知情的狀況下完成想要達到的目的;當然,缺點就是這種方式只適用在M$ Windows的作業系統,而且Server上還必須要有M$ Office...

雖然說是直接上傳Excel檔轉入資料,但說穿了不過是利用COM()函數在使用者不知情的情況下另存成csv檔後,再作處理。以下是利用COM()函數另存新檔的程式碼:

$excel = new COM("excel.application") or die("Unable to instanciate excel"); //調用COM class,順便判斷是否能正常連結Excel應用程式
$excel->DisplayAlerts = 0; //關閉開啟Excel時的警告
$strTemp = 'C:\\xxx\\xxx\\xxx\\csv\\'.$file_name; //上傳成功檔案的絕對路徑
$excel->Workbooks->Open($strTemp); //打開該檔案
$csvfile_name = substr($file_name, 0,strlen($file_name)-4).'.csv'; //利用原檔名將副檔名改寫成csv
$strTemp = 'C:\\xxx\\xxx\\xxx\\csv\\'.$csvfile_name; //另存成csv檔後的絕對路徑
$excel->ActiveWorkbook->SaveAs($strTemp ,6); //另存新檔,6代表csv逗號分隔檔案
$excel->Quit(); //退出Excel
//$excel->Release(); //釋放Excel所佔用的記憶體...吧?不過我的電腦必須註解掉這行才能動作,不知道為什麼
$excel = null; //釋放Excel所佔用的記憶體...吧?其實我不太知道這跟上面有什麼不同

下來就是利用另存的csv檔對資料做處理囉!基本上作法沒有變,只是使用者可以省略自己另存的動作,而由Server代替轉存,使用者自然會覺得方便許多。可惜本公司的Server雖然是M$ Windows系統,但是並沒有安裝M$ Office;所以只能用第二種方法囉。

第二種方法是偉大的前輩事先做好的class:PHP-ExcelReader。PHP真不愧為網路程式設計的龍頭,許多功能其實前輩們都已經想好了!其實主要用的的檔案也只有二個:oleread.inc跟reader.php。而且因為已經封裝成class,使用方面也非常的簡單,以下式簡單的程式碼:

require_once '../Excel/reader.php';
$data = new Spreadsheet_Excel_Reader(); //調用Spreadsheet_Excel_Reader class
$data->setOutputEncoding('utf-8'); //設定輸出的編碼,可直接選擇輸出為UTF8編碼
$data->read("../xxx/xxx/test.xls"); //檔案的路徑(可使用相對路徑)
error_reporting(E_ALL ^ E_NOTICE); //錯誤顯示

for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
for ($j = 1; $j <= $data->sheets[0]['numCols']; $j++) {
echo "\"".$data->sheets[0]['cells'][$i][$j]."\",";
}
echo "\n";
}

利用陣列的方式,擷取Excel檔裡面的資料;['numRows']列、['numCols']行、['cells']元素,搭配二維陣列取得。擷取出來的資料就可以直接對其作處理,非常容易使用!

關於Excel檔寫入也有另一個class:Spreadsheet_Excel_Writer。這個class需要pear的支援,所以使用前必須先安裝pear;這個部份我還沒有深入研究測試,就先行打住。另外還有一個class比較新,是支援M$ Office Excel 2007的格式:PHPExcel。這個class同時支援讀入跟寫出,不過目前只針對Excel 2007的版本作處理。目前我們公司仍以2003為主,所以這個版本也沒有深究。當然2007一定是未來的趨勢,所以以後應該還是有機會會接觸到吧

0 Comments:

張貼留言

<< Home