在做導出一個信息表為excel文件這個功能完成之后,自己用得好好的,但是到HR那邊就告訴我導出的文件無法用她電腦上的office打開,心想,兼容沒做好,想問下她的版本號,結果半天沒回復消息。
我老大來了句:轉csv文件吧,沒有兼容性的說法。
然后開始折騰csv,在這之前我只是見過“導出csv文件”的字樣,沒有涉及過這個。
當然一開始要去了解一下csv是什么: https://baike.baidu.com/item/CSV/10739。
先附上代碼:
public function exportCSVAction()
{
$id = (int)$this->_req->getParam('cid',0);
$reg = new RegistrationModel();
$studentsArr = $reg->getStudents($id); // 獲取課程及報名學員信息
$fileName = $studentsArr['info']['title']; //這里定義表名。簡單點的就直接 $fileName = time();
header('Content-Type: application/vnd.ms-excel'); //header設置
header("Content-Disposition: attachment;filename=".$fileName.".csv");
header('Cache-Control: max-age=0');
$fp = fopen('php://output','a'); //打開php文件句柄,php://output表示直接輸出到PHP緩存,a表示將輸出的內容追加到文件末尾
$head = array('工號','部門名','崗位名','學員名','報名時間','狀態','課程建議'); //表頭信息
foreach($head as $k=>$v){
$head[$k] = iconv("UTF-8","GBK//IGNORE",$v); //將utf-8編碼轉為gbk。理由是: Excel 以 ANSI 格式打開,不會做編碼識別。如果直接用 Excel 打開 UTF-8 編碼的 CSV 文件會導致漢字部分出現亂碼。
}
fputcsv($fp,$head); //fputcsv() 函數將行格式$head化為 CSV 並寫入一個打開的文件$fp。
// if (!empty($studentsArr['students'])) {
$data = []; //要導出的數據的順序與表頭一致;提前將最后的值准備好(比如:時間戳轉為日期等)
foreach ($studentsArr['students'] as $key => $val) {
$data['empno'] = "xm-".$val['empno'];
$data['dept'] = $val['dept_name'].'-'.$val['job_name'];
$data['post'] = $val['post'];
$data['username'] = $val['username'];
$data['create_time'] = " ".date('Y-m-d H:i', $val['create_time']); //excel對大數字會自動轉科學計數法表示,所以這里加個“”空格是將數字轉字符串,這個有多種方式,具體怎么方便怎么來。
switch ($val['status']) {
case 0:
$data['status'] = '請假';
break;
case 1:
$data['status'] = '正常';
break;
case 2:
$data['status'] = '已取消';
break;
case 3:
$data['status'] = '缺席';
break;
}
$data['advices'] = $val['advices'];
foreach($data as $i=> $item){ //$item為一維數組哦
$data[$i] = iconv("UTF-8","GBK//IGNORE",$item); //轉為gbk的時候可能會遇到特殊字符‘-’之類的會報錯,加 ignore表示這個特殊字符直接忽略不做轉換。
}
fputcsv($fp,$data);
}
exit; //記得加這個,不然會跳轉到某個頁面。
// }
}
過程中遇到知識點:
* iconv的使用:http://php.net/manual/zh/function.iconv.php;
* fputcsv的使用:http://php.net/manual/zh/function.fputcsv.php。
注意點:
-
頁面導出按鈕應該直接使用url地址跳轉的方式,如果使用ajax跳轉到導出方法會無法導出文件,並返回一堆亂碼的數據。
這是因為ajax請求需要有返回數據,返回數據就會帶有自己的請求頭部,會與下載文件頭部沖突掉,導致文件無法下載。 -
我這里的工號其實有存在前面的數字為0的情況(比如:0123、0001),導出的文件用excel打開后就變成123、1 啦,這明顯不合我的要求。
解決方式是在要處理的字段前加個轉義符‘`’(英文輸入法下的tab鍵上方的鍵),據說微信導數據是這樣處理的。
我的解決方式是:因為是公司工號,我加了公司前綴,比如: c_0123;
