轉入之後當然接下來的就是轉出囉!我原本採用的轉出方法是非常陽春的斷欄「\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的無限可能~也學到不少東西哩!最後我對日期的處理方式,是消極的用錯誤訊息防止使用者匯入錯誤格式;這也不失為解決問題的其中一個方法啦!^^