轉入之後當然接下來的就是轉出囉!我原本採用的轉出方法是非常陽春的斷欄「\t」與斷行「\n」的應用,所以在使用M Excel 2007時總是會出現錯誤訊息提示。與轉入的方式比較起來,Excel檔案轉出的方式似乎比較多:PHP導入導出Excel方法小結。裡面共介紹6種方式不巧在下小弟我因為儲存格格式的問題,幾乎把所有方法都試過一遍了...下面來分別介紹使用方式與心得吧!
1、PHPExcel:PHPExcel,一個最好的控制excel的類
非常可惜的這是我能找到介紹最完整的網路說明這套class是屬於非常新的一個class,所以關於用法網路上並沒有介紹的很詳細;官方網站裡的說明文件也非常陽春...雖然功能強大,而且通吃M Excel 2007及其以下的各版本,文章裡大力推薦,但是因為說明文件資料不足、網上範例太少、寫入時採用英文字母,很難用迴圈跑出來(汗)、儲存格格式無法設定...等原因,最後放棄這一個方法。
/*PHPExcel使用*/
error_reporting(E_ALL); //開啟錯誤顯示(?)
set_include_path(get_include_path() . PATH_SEPARATOR . '../Excel/'); //設定class路徑
include 'PHPExcel.php'; //include必要程式
include 'PHPExcel/Writer/Excel5.php'; //使用Excel 2003以下的版本
objPHPExcel = new PHPExcel(); //調用PHPExcel class
objWriter = new PHPExcel_Writer_Excel5(objPHPExcel); //調用Excel 2003以下的版本
objPHPExcel->setActiveSheetIndex(0); //設定動作Sheet
objPHPExcel->getActiveSheet()->setCellValue('A1', '日期'); //指定A1儲存格內容
objPHPExcel->getActiveSheet()->setCellValue('B1', '姓名'); //指定B1儲存格內容
objPHPExcel->getActiveSheet()->setCellValue('C1', '上班時數'); //指定C1儲存格內容
objPHPExcel->getActiveSheet()->setCellValue('D1', '加班時數'); //指定D1儲存格內容
objPHPExcel->getActiveSheet()->setCellValue('E1', '工程案號'); //指定E1儲存格內容
objPHPExcel->getActiveSheet()->setTitle('Simple'); //指定Sheet名稱
objWriter->save('error_log.xls'); //另存Excel檔案
最後儲存的檔案會再放置網頁的資料夾中,如果要讓使用者另存下載,就必須加上header。
2、pear的Spreadsheet_Excel_Writer:關於PEAR類庫中用於操作EXCEL的類庫Spreadsheet_Excel_Writer
這算是一種歷史悠久的方法,運用PHP非常強大的函式庫pear;關於pear我其實一直不是很了解,這次剛好藉由這次機會接觸。首先是pear的安裝,實際跑過一遍以後才發現原來安裝這麼容易:直接執行PHP目錄下的「go-pear.bat」,安裝過程一直按「Enter」就OK了!安裝完成以後,PHP目錄下PEAR的目錄裡面就會有資料了,此時pear就算安裝完成啦!接下來是Spreadsheet_Excel_Writer的安裝;在命令提示字元下執行:
pear install OLE-0.5
pear install Spreadsheet_Excel_Writer-0.9.1
pear就會自動上網下載與安裝!感覺好linux唷安裝也變得非常容易。全部安裝完成以後,只剩下要注意pear在PHP裡的path路徑是否正確,就可以直接include進來囉!使用Spreadsheet_Excel_Writer唯一比較麻煩的是必須先安裝pear及其函式庫,使用上非常便利。原本是我心目中的第一首選!不過不知道為什麼,我們公司的伺服器pear裝不起來,試了好久都不行;雖然網路上說可以直接COPY pear整個資料夾再設定path,不過因為怕不正確安裝會導致不可預期的後果,且儲存格格式也是無法設定;所以放棄此一方法。
/*PEAR的Spreadsheet_Excel_Writer*/
require_once 'Spreadsheet/Excel/Writer.php'; //require必要程式
workbook = new Spreadsheet_Excel_Writer(); //調用Spreadsheet_Excel_Writer class
workbook->setVersion(8); //設定Excel版本為XP以上
worksheet =& workbook->addWorksheet('Sheet1'); //增加一個Sheet
worksheet->setInputEncoding('utf-8'); //設定編碼為UTF
format_locked =& workbook->addFormat();
format_locked -> setLocked(); //設定鎖定格式,防止別人修改
//worksheet->setColumn(0,255,8.38,format_locked); //此為指定整個工作表鎖定狀態
worksheet->writeString(0, 0, '日期'); //設定(0,0)儲存格內容
worksheet->writeString(0, 1, '姓名'); //設定(0,1)儲存格內容
worksheet->writeString(0, 2, '上班時數'); //設定(0,2)儲存格內容
worksheet->writeString(0, 3, '加班時數'); //設定(0,3)儲存格內容
worksheet->writeString(0, 4, '工程案號'); //設定(0,4)儲存格內容
//錯誤資料寫入Excel
for (i = 1;i <= error_row;i++){
for (j = 1;j <= 5;j++){
worksheet->write(i, j-1, error_msg[i][j]);
}
}
workbook->send('error_log.xls'); //另存下載Excel檔案
workbook->close(); //關閉(?)
3、XML轉出:使用 PHP 輸出帶格式的 Excel 文件
話說M Excel從2003開始,導入了對XML檔案的支援,終於冥頑不靈的M也向開放性格事低頭了呢!只要由PHP輸出正確的XML格式,再另存成xls檔就可以餵給Excel讀了吧...本來是這樣想的...沒想到我用的M Excel 2007在另存成XML檔時好像還得經過些設定;我整個不知道要怎麼做啊!在不確定因素及設定太過複雜的情況下,我放棄了這個方法(其實也是懶得弄一些有的沒的啦...)
4、利用pack()函數將資料包裝使其接近Excel格式:這段操作excel的代碼應該怎麼操作設置每列的寬度
如同標題說,就是利用pack()函數將資料包裝使其接近Excel格式。Excel的格式是M自定的一種資料格式,這個方法是利用PHP的pack()函數,把我們所需的資料包裝成接近Excel原始格式的一種方法;其實說穿了不過就是把「\t」「\n」替換掉的另一種陽春的方法。不過這種方是因為接近Excel原始格式,所以在開啟的時候並不會有錯誤訊息提示,算是一種簡單易懂又最貼近Excel格式的方法。文章裡也推薦這個方法,所以最後我採用了這個方式雖然它仍然無法設定儲存格格式...(汗)
/*利用pack()函數將資料包裝使其接近Excel格式*/
filename = 'error_log.xls'; //設定另存下載檔案名稱
header ('Content-type: application/x-msexcel'); //送出header
header ("Content-Disposition: attachment; filename={filename}" );
xlsBOF(); //起始包裝函數
//標題列
xlsWriteLabel(0, 0, u2b('日期')); //設定(0,0)儲存格內容,儲存格內容為文字
xlsWriteLabel(0, 1, u2b('姓名')); //設定(0,1)儲存格內容,儲存格內容為文字
xlsWriteLabel(0, 2, u2b('上班時數')); //設定(0,2)儲存格內容,儲存格內容為文字
xlsWriteLabel(0, 3, u2b('加班時數')); //設定(0,3)儲存格內容,儲存格內容為文字
xlsWriteLabel(0, 4, u2b('工程案號')); //設定(0,4)儲存格內容,儲存格內容為文字
//錯誤列
for (i = 0;i < error_row;i++){
xlsWriteLabel(i + 1, 0, error_msg[i][0]); //設定(i + 1,0)儲存格內容,儲存格內容為文字
xlsWriteLabel(i + 1, 1, error_msg[i][1]); //設定(i + 1,1)儲存格內容,儲存格內容為文字
xlsWriteNumber(i + 1, 2, error_msg[i][2]); //設定(i + 1,2)儲存格內容,儲存格內容為數字
xlsWriteNumber(i + 1, 3, error_msg[i][3]); //設定(i + 1,3)儲存格內容,儲存格內容為數字
xlsWriteLabel(i + 1, 4, error_msg[i][4]); //設定(i + 1,4)儲存格內容,儲存格內容為文字
}
xlsEOF(); //結束包裝函數
//Excel生成用函數,起始包裝
function xlsBOF() {
echo pack("ssssss", 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);
return;
}
//Excel生成用函數,結束包裝
function xlsEOF() {
echo pack("ss", 0x0A, 0x00);
return;
}
//Excel生成用函數,數字包裝用
function xlsWriteNumber(Row, Col, Value) {
echo pack("sssss", 0x203, 14, Row, Col, 0x0);
echo pack("d", Value);
return;
}
//Excel生成用函數,文字包裝用
function xlsWriteLabel(Row, Col, Value ) {
L = strlen(Value);
echo pack("ssssss", 0x204, 8 + L, Row, Col, 0x0, L);
echo Value;
return;
}
5、使用「\t」、「\n」的方法:
這就是我原來使用的方法,雖然簡單易懂易用,但是因為用M Excel 2007開啟時總是會出現錯誤訊息提示所以才換掉。順便一提,它也沒辦法設定儲存格格式。
/*最原始的\t\n用法*/
filename = 'error_log.xls'; //設定另存下載檔案名稱
header("Content-Type: application/vnd.ms-excel"); //送出header,這我是直接從網路上抄來的
header("Content-Disposition:filename=sub.xls");
header("Content-Disposition: attachment; filename={filename}");
header("Pragma: no-cache");
header("Expires: 0");
error = ''; //起始錯誤字串的值
//
for (i = 1;i <= error_row;i++){
for (j = 1;j <= 5;j++){
error .= error_msg[i][j]."\t"; //跨欄
}
error .= "\n"; //斷行
}
echo error; //印出完整錯誤字串
6、使用com()函數:
這個方式應該是設定功能最完整個方法!因為它是直接調用Server端的M Excel來產生檔案的,關於這個方法我沒有實際研究。因為這個方法有限制:它只適用在Server為M Windows作業系統平台,且必須安裝M Office才能用;也就是說,如果作業平台是Linux,或是沒有安裝M Office就不能用。非常剛好的,我們公司的Server雖然是M Windows作業系統平台,卻沒有安裝M Office...想當然爾我就放棄這個方法啦!不過這或許是唯一一個可以設定儲存格格式的方法...
很難想像為了儲存格格式,我把網路上傳授的6種方法幾乎都試過了...雖然最後仍然沒有解決我的問題,不過因此而認識到PHP的無限可能也學到不少東西哩!最後我對日期的處理方式,是消極的用錯誤訊息防止使用者匯入錯誤格式;這也不失為解決問題的其中一個方法啦!
