使用PHPExcel要點(diǎn)解析
我們?cè)诰W(wǎng)站開發(fā)中經(jīng)常都會(huì)用到PHP,來幫助我們實(shí)現(xiàn)許多功能需求。在處理數(shù)據(jù)庫(kù)時(shí),通常都會(huì)使用PHPExcel,那么在實(shí)際使用中又會(huì)出現(xiàn)各種問題,值得我們?nèi)ド钊胙芯俊?t#
以前準(zhǔn)備做一個(gè)PHP將excel導(dǎo)入mysql數(shù)據(jù)庫(kù)的通用程序,基本完成之后就沒有管它了。上個(gè)月,教務(wù)處老師叫我?guī)兔ψ鲆粋€(gè)“國(guó)家等級(jí)考試報(bào)名查詢系統(tǒng)”,也需要將學(xué)生excel信息導(dǎo)入導(dǎo)出,照片zip壓縮導(dǎo)入導(dǎo)出。
上一周剛完成這個(gè)程序,雖然用java這樣的語(yǔ)言處理比較簡(jiǎn)單,不過PHP增加這個(gè)功能卻是5.2以上的版本才能夠完成(需要新增的PHP_zip擴(kuò)展)。畢竟一個(gè)月的接觸,也略微懂了一些最基礎(chǔ)的用法,也遇到了一起才起手很容易碰到的問題,網(wǎng)上關(guān)于這個(gè)介紹比較簡(jiǎn)略,我想具體的介紹一下它的基本用法和可能遇到的基本問題。
首先,你需要打開PHP_zip擴(kuò)展,找到你起作用的PHP.INI文件,并打開這個(gè)擴(kuò)展,將PHP文件夾里面的ext文件夾中的PHP_zip.dll文件找到,并復(fù)制到system32系統(tǒng)文件夾中(具體要看你的配置方法)。
網(wǎng)上最多的問題就是使用PHPExcel的時(shí)候,沒有打開這個(gè)擴(kuò)展。就會(huì)顯示諸如<Fatal error:Class 'ZipArchive' not found in …..的錯(cuò)誤,就是這個(gè)原因。然后,就可以使用它了,最好的辦法是看它自帶的test示例文檔,就可以大概知道它的基本用法,當(dāng)然看完自帶的test示例文檔后,這篇文章也可能對(duì)你整體理解有一定好處。
下面我只想說說一些需要注意和容易錯(cuò)的地方。
1.使用PHPExcel創(chuàng)建excel文檔對(duì)象有2種。
一種是直接創(chuàng)建
include 'PHPExcel/Writer/Excel2007.PHP';
$objPHPExcel = new PHPExcel();
另外一種是通過reader類進(jìn)行讀取創(chuàng)建
require 'PHPExcel/Reader/Excel2007.PHP';
$objReader = new PHPExcel_Reader_Excel2007;
$objPHPExcel = $objReader->load("mytest.xlsx");
我這里想說明的是,這里包含excel2007.PHP, 就是創(chuàng)建的xlsx類型的excel,也就是ms office2007打開的,如果要?jiǎng)?chuàng)建以前的xls的話(office2007以前版本),就需要包含excel5.PHP,而不是 excel2007,不管是reader類還是writer類,這個(gè)要注意。比如上面說的2種用法就應(yīng)該直接創(chuàng)建:
include 'PHPExcel/Writer/Excel5.PHP';
$objPHPExcel = new PHPExcel();
通過reader類進(jìn)行讀取創(chuàng)建
require 'PHPExcel/Reader/Excel5.PHP';
$objReader = new PHPExcel_Reader_Excel5;
$objPHPExcel = $objReader->load("mytest.xlsx");
2.看了使用PHPExcel給出的文檔之后很有可能問,我就是想讀取excel的一個(gè)單元格的值,怎么沒有給出怎么讀呢?這個(gè)開始我也遇到過,你可以這樣:
$sheet = $objPHPExcel->getActiveSheet();
$string = $sheet->getCell('F2')->getValue();
當(dāng)然,這個(gè)一般情況下也是能用了,如果你的excel是公式,你就應(yīng)該
$sheet = $objPHPExcel->getActiveSheet();
$string = $sheet->getCell('F2')-> getCalculatedValue();
3.使用PHPExcel關(guān)于長(zhǎng)數(shù)字被轉(zhuǎn)換成科學(xué)計(jì)數(shù)法的問題。
并且最后幾位被忽略為0,這個(gè)問題困擾了我很久,就是比如身份證,學(xué)號(hào)這樣的數(shù)字,如果你直接setValue的話,出來的excel被自動(dòng)轉(zhuǎn)換成科學(xué)計(jì)數(shù)法,網(wǎng)上本來這樣的資料少,而且我發(fā)現(xiàn)大多數(shù)還是錯(cuò)的。我查到了一篇文檔,是通過改動(dòng)PHPexcel源碼實(shí)現(xiàn)的
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的時(shí)候通過以文本格式寫入就可以了(不修改源代碼以 文本格式寫入也是科學(xué)技術(shù) 法)
$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的列數(shù)和行數(shù)?
往往開始使用PHPexcel會(huì)覺得不好用的地方也是如此,因?yàn)樗膖est示例程序也沒有給出這個(gè)。以下是我在codeplex問的問題以及解答。大家看了也就知道了(帖子后面圖片)。
5.使用PHPExcel如何通過循環(huán)得到每一個(gè)單元格的值。
ObjPHPExcel這個(gè)對(duì)象你print_r輸出會(huì) 看到很多復(fù)雜的東西,其實(shí)通過自帶的方法會(huì)很簡(jiǎn)單。我是采用這樣的方法
$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');
通過設(shè)置一個(gè)字符的數(shù)組,就可以用循環(huán)變量循環(huán)列數(shù)了。這里我還出了個(gè)小笑話,以前我居然想通過A字符轉(zhuǎn)換為ASC碼來循環(huán),未果,我翻了一下PHP的書才知道PHP轉(zhuǎn)換字符成整形和C,C++不是一樣的,真是基礎(chǔ)不扎實(shí)啊。
6.使用PHPExcel關(guān)于數(shù)據(jù)庫(kù)和excel的編碼問題。
這個(gè)也需要大家注意,excel是采用的UTF-8編碼,于是你每次從數(shù)據(jù)庫(kù)讀出數(shù)據(jù)后,應(yīng)該不要忘了轉(zhuǎn)換一次。
$this->student_info[$i][$j]=iconv("gbk","UTF-8",$this->student_info[$i][$j]);但是記住,問題卻沒有這樣簡(jiǎn)單,當(dāng)你使用PHPExcel從excel讀取數(shù)據(jù)的時(shí)候,可能會(huì)發(fā)現(xiàn)居然有漢字的列會(huì)沒有讀出來,是空的。
用print_r打印出來一看,那個(gè)單元格也是空的,這個(gè)并不是轉(zhuǎn)換編碼問題,因?yàn)槿绻蔷幋a,應(yīng)該打印出亂碼, 這個(gè)卻是PHPexcel沒有讀出那一列的漢字。這個(gè)問題我也不是太明白,我打開reader的excel5.PHP文件 把$this->_defaultEncoding = 'isoXXXXX';改為$this->_defaultEncoding = 'UTF-8';解決的,就能讀出亂碼了,之后可以通過轉(zhuǎn)換編碼解決。我在官方網(wǎng)站問了也未果,大家有更好的方法也可以跟我說說,謝謝。