我們在網站開發中經常都會用到
以前准備做一個PHP將excel導入mysql數據庫的通用程序,基本完成之後就沒有管它了。上個月,教務處老師叫我幫忙做一個“國家等級考試報名查詢系統”,也需要將學生excel信息導入導出,照片zip壓縮導入導出。
上一周剛完成這個程序,雖然用java這樣的語言處理比較簡單,不過PHP增加這個功能卻是5.2以上的版本才能夠完成(需要新增的PHP_zip擴展)。畢竟一個月的接觸,也略微懂了一些最基礎的用法,也遇到了一起才起手很容易碰到的問題,網上關於這個介紹比較簡略,我想具體的介紹一下它的基本用法和可能遇到的基本問題。
首先,你需要打開PHP_zip擴展,找到你起作用的PHP.INI文件,並打開這個擴展,將PHP文件夾裡面的ext文件夾中的PHP_zip.dll文件找到,並復制到system32系統文件夾中(具體要看你的配置方法)。
網上最多的問題就是使用PHPExcel的時候,沒有打開這個擴展。就會顯示諸如<Fatal error:Class 'ZipArchive' not found in …..的錯誤,就是這個原因。然後,就可以使用它了,最好的辦法是看它自帶的test示例文檔,就可以大概知道它的基本用法,當然看完自帶的test示例文檔後,這篇文章也可能對你整體理解有一定好處。
下面我只想說說一些需要注意和容易錯的地方。
1.使用PHPExcel創建excel文檔對象有2種。
一種是直接創建
include 'PHPExcel/Writer/Excel2007.PHP';
$objPHPExcel = new PHPExcel();
另外一種是通過reader類進行讀取創建
require 'PHPExcel/Reader/Excel2007.PHP';
$objReader = new PHPExcel_Reader_Excel2007;
$objPHPExcel = $objReader->load("mytest.xlsx");
我這裡想說明的是,這裡包含excel2007.PHP, 就是創建的xlsx類型的excel,也就是ms office2007打開的,如果要創建以前的xls的話(office2007以前版本),就需要包含excel5.PHP,而不是 excel2007,不管是reader類還是writer類,這個要注意。比如上面說的2種用法就應該直接創建:
include 'PHPExcel/Writer/Excel5.PHP';
$objPHPExcel = new PHPExcel();
通過reader類進行讀取創建
require 'PHPExcel/Reader/Excel5.PHP';
$objReader = new PHPExcel_Reader_Excel5;
$objPHPExcel = $objReader->load("mytest.xlsx");
2.看了使用PHPExcel給出的文檔之後很有可能問,我就是想讀取excel的一個單元格的值,怎麼沒有給出怎麼讀呢?這個開始我也遇到過,你可以這樣:
$sheet = $objPHPExcel->getActiveSheet();
$string = $sheet->getCell('F2')->getValue();
當然,這個一般情況下也是能用了,如果你的excel是公式,你就應該
$sheet = $objPHPExcel->getActiveSheet();
$string = $sheet->getCell('F2')-> getCalculatedValue();
3.使用PHPExcel關於長數字被轉換成科學計數法的問題。
並且最後幾位被忽略為0,這個問題困擾了我很久,就是比如身份證,學號這樣的數字,如果你直接setValue的話,出來的excel被自動轉換成科學計數法,網上本來這樣的資料少,而且我發現大多數還是錯的。我查到了一篇文檔,是通過改動PHPexcel源碼實現的
Writer/Excel5文件,第202行,
- if ($cell->hasHyperlink()) {
- $worksheet->writeUrl($row, $column,
str_replace('sheet://', 'internal:',
$cell->getHyperlink()->getUrl()),
$cell->getValue(), $formats[$styleHash]);- }
- else {
- $worksheet->write($row, $column, $cell->
getValue(), $formats[$styleHash],$style->
getNumberFormat()->getFormatCode());- }
- 改為if ($cell->hasHyperlink()) {
- $worksheet->writeUrl($row, $column,
str_replace('sheet://', 'internal:',
$cell->getHyperlink()->getUrl()), $cell->
getValue(), $formats[$styleHash]);- }else if($cell->getDataType() ==
PHPExcel_Cell_DataType::TYPE_STRING ) {- $worksheet->writeString($row,$column,$cell->
getValue(),$formats[$styleHash]);- }
- else {
- $worksheet->write($row,$column,$cell->
getValue(),$formats[$styleHash],$style->
getNumberFormat()->getFormatCode());}
然後寫入excel的時候通過以文本格式寫入就可以了(不修改源代碼以 文本格式寫入也是科學技術 法)
$objPHPExcel->getActiveSheet()->setCellValueExplicit($letters_arr[$j+1] . ($i+1),$this->student_info[$i][$j],PHPExcel_Cell_DataType::TYPE_STRING);
$objPHPExcel->getActiveSheet()->getStyle($letters_arr[$j+1] . ($i+1))->getNumberFormat()->setFormatCode("@");
4.使用PHPExcel如何得到excel的列數和行數?
往往開始使用PHPexcel會覺得不好用的地方也是如此,因為它的test示例程序也沒有給出這個。以下是我在codeplex問的問題以及解答。大家看了也就知道了(帖子後面圖片)。
5.使用PHPExcel如何通過循環得到每一個單元格的值。
ObjPHPExcel這個對象你print_r輸出會 看到很多復雜的東西,其實通過自帶的方法會很簡單。我是采用這樣的方法
$letters_arr = array(1=>'A',2=>'B',3=>'C',4=>'D',5=>'E',6=>'F',7=>'G',8=>'H',9=>'I',10=>'J',11=>'K',12=>'L',13=>'M', 14=>'N',15=>'O',16=>'P',17=>'Q',18=>'R',19=>'S',20=>'T',21=>'U',22=>'V',23=>'W',24=>'X',25=>'Y',26=>'Z');
通過設置一個字符的數組,就可以用循環變量循環列數了。這裡我還出了個小笑話,以前我居然想通過A字符轉換為ASC碼來循環,未果,我翻了一下PHP的書才知道PHP轉換字符成整形和C,C++不是一樣的,真是基礎不扎實啊。
6.使用PHPExcel關於數據庫和excel的編碼問題。
這個也需要大家注意,excel是采用的UTF-8編碼,於是你每次從數據庫讀出數據後,應該不要忘了轉換一次。
$this->student_info[$i][$j]=iconv("gbk","UTF-8",$this->student_info[$i][$j]);但是記住,問題卻沒有這樣簡單,當你使用PHPExcel從excel讀取數據的時候,可能會發現居然有漢字的列會沒有讀出來,是空的。
用print_r打印出來一看,那個單元格也是空的,這個並不是轉換編碼問題,因為如果是編碼,應該打印出亂碼, 這個卻是PHPexcel沒有讀出那一列的漢字。這個問題我也不是太明白,我打開reader的excel5.PHP文件 把$this->_defaultEncoding = 'isoXXXXX';改為$this->_defaultEncoding = 'UTF-8';解決的,就能讀出亂碼了,之後可以通過轉換編碼解決。我在官方網站問了也未果,大家有更好的方法也可以跟我說說,謝謝。