打造最全面的PHPExcel開發解決方案

過去工做中使用PHPExcel較多,碰到並解決了各類大大小小的問題,總結出這樣一篇文章,一方面記錄本身踩過的坑,一方面與你們分享,讓你們少走彎路,並不斷完善之,歡迎你們去github上面star和提交pull request,不斷補充和優化,打造最全面的PHPExcel開發解決方案php

Github 地址:https://github.com/tony-yin/P...
原文地址:https://tony-yin.github.io/20...html

基礎:小試牛刀

1. 引用文件

yourpath . /phpexcel/PHPExcel.php

2. 實例化phpexcel類

$excel = new PHPExcel();

3. 獲取當前單sheet(多sheet會在下面講)

$objexcel = $excel->getActiveSheet();

4. 合併單元格

$objexcel->mergeCells('A1:M1');

5. 獲取一個cell的樣式

$objexcel->getStyle('A1');
  • 獲取一個cell的字體樣式
$cellFont = $objexcel->getStyle('A1')->getFont();
  • 設置字體大小
$fontStyle->setSize(15);
  • 設置字體是否加粗
$fontStyle->setBold(true);
  • 設置字體顏色
$fontStyle->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);
  • 獲取一行樣式
$rowStyle = $objexcel->getStyle(1)->getRowDimension();
  • 設置行高度
$rowStyle->setRowHeight(2);
  • 獲取一列樣式
$columnStyle = $objexcel->getStyle('A')->getColumnDimension();
  • 設置列寬度
$columnStyle->setWidth(10);
  • 獲取一列對齊樣式
$alignStyle = $objexcel->getStyle('A')->getAlignment();
  • 設置水平居中:同一水平線上居中,即爲左右的中間
$alignStyle>setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  • 設置垂直居中:同一垂直線居中,即爲上下的中間
$alignStyle->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
  • 自動換行
$$alignStyle->setWrapText(true);

6. 獲取指定版本excel寫對象

如需更早的版本可將Excel2007換成Excel5git

$write = PHPExcel_IOFactory::createWriter("xcel, 'Excel2007');

進階:一些有用的小知識

1.行列數字索引方法

phpexcel通常獲取cell或者獲取列都是經過ABC這樣的英文字母獲取的,它也能夠經過0、一、二、3這樣的數字表示sheet中的列,從0開始,0對應A1對應B,基本上大多數方法都是數字行列索引,例如getStyleByColumnAndRow($col,$row),默認列參數在前,行參數在後,更多的能夠參加phpexcel源碼;github

2. 單行或單列參數格式

有的時候一個方法須要行列兩個參數,例如只須要某一行參數可寫成(null, $row),例如只須要得到某一列參數可寫成($col, null)算法

3. 列的數字索引格式和字母索引格式互轉

  • 數字轉字符串
PHPExcel_Cell::columnIndexFromString('A');  // Return 1 not 0;
  • 字符串轉數字
PHPExcel_Cell::stringFromColumnIndex(0);    // Return 'A';

4.PHPExcel讀取數字類型

PHPExcel讀取的cell數字,類型都是double型,可用gettyle()方法檢測類型,當初我一直使用is_int()方法無果,搞得焦頭爛額。。。瀏覽器

5. 多cell邊框線設置

PHPExcel生成的表格若是你不加處理,是不會幫你生成邊框線的,生成邊框線的方法以下:app

$borderArray = array(
    'borders' => array(
        'allborders' => array(
            'style' => PHPExcel_Style_Border::BORDER_THIN
        )
    )
);
$objexcel->getStyle($col1, $row1,$col2, $row2)->applyFromArray($borderArray);

注:函數

  1. getStyle()能夠看需求改成getStyleByColumnAndRow()方法經過數字行列索引讀取style
  2. array中PHPExcel_Style_Border::後面有三種格式分別是BORDER_THINBORDR_MEDIUM,表示邊框線的粗細;
  3. getStyle()中的索引能夠是靜態的,也能夠是動態的,通常是在導出excel的數據set完畢後填寫左上角的單元格行列索引和右下角的單元格行列索引;

參考資料性能

http://phpexcel.codeplex.com/...
http://phpexcel.codeplex.com/...字體

6. 多cell字體加粗處理

$objexcel->getStyle($pCoordinate)->applyFromArray(array(
    'font' => array(  
        'bold' => true,                                              
    ),                                                               
));

7. 多cell字體顏色處理

$objexcel->getStyle($pCoordinate)->applyFromArray(array(
    'font' => array(
        'color' => array(
            'rgb' => 'ff0000',
            ),
        ),
    )
);

8. 多sheet導入

動態爲當前sheet設置索引,而後獲取當前sheet,即可循環讀取每個sheet內容

$objexcel->setActiveSheetIndex($index);   //$index = 0 1 2 3
$objexcel->getActiveSheet();    //return sheet1 sheet2 sheet 3

9. 固定格式excel讀取在寫入

當需求是給定一個一個模板excel,須要往裏面塞數據,咱們不必定要經過代碼給它設定樣式,若是這個模板變化不大,咱們徹底能夠存放一個格式相同的靜態文件,而後經過PHPExcel讀取,再往裏面塞數據,最後進行保存操做,能夠達到同樣的效果,而且能夠節省大量的資源。

10. 合併單元格導入問題

在特殊的表格中,合併單元格廣泛存在,而多個單元格合併成的一個單元格,只能setValue()一次,而咱們如何判斷合併單元格的具體行列呢?

$range = $start_cell->getMergeRange();  // 經過合併單元格的開始單元格好比‘A1’,獲取合併範圍‘A1:A4’
$cell->isInRange($range);    // 遍歷以後每個單元格即可經過isInRange()方法判斷當前單元格是否在合併範圍內

高級:特殊場景特殊手段

1. 單元格文本格式數據處理

通常excel單元格中數據的格式爲數據類型,而PHPExcel中的getValue()方法讀取的也是數據類型,當把數據從數據類型改成文本類型後,在PHPExcel中讀出來的是PHPExcel_RichText類型,getValue()讀取返回PHPExcel_RichText是一個object類型(PHPExcel_RichText數據保存格式);那如何讀取這一類的數據呢?仔細查看讀取出來的對象,不難發現有getPlainText()這樣的方法能夠讀取文本類型數據,因此咱們只要判斷噹噹前數據爲文本數據時用getPlainText()讀取,通常數據用getValue()讀取

if ($cell->getValue() instanceof PHPExcel_RichText) {
    $value = $cell->getValue();
} else {
    $value = $cell->getValue();
}

參考資料

http://www.cnblogs.com/DS-CzY...
http://phpexcel.codeplex.com/...

2. 單元格數據算法處理

excel擁有強大的算法功能,通常算法格式爲=A3+A4這類的,複雜的更多,若是使用PHPExcel提供的默認讀取方法getValue()讀取出來的結果則爲字符串=A3+A4,好在PHPExcel也足夠強大,提供了相應的接口:getCalculatedValue(),這個方法專門讀取算法數據,可是咱們不能將這個方法做爲默認讀取方法,由於這樣可能會將一些原本要讀成字符串的讀成算法數據,並且PHPExcel沒有將它做爲默認讀取方法的另外一個重要緣由就是算法方式讀取很耗時間和性能,通常數據讀取根本沒有必要這樣浪費資源,因此咱們能夠採用如下這種方式

if (strstr($cell->getValue(), '=')) {   
    // 判斷若是cell內容以=號開頭便默認爲算法數據
    $value = $cell->getCalculatedValue(); 
} else {
    $value = $cell->getValue();
}

3. 日期數據處理

除了以上所說的文本數據和算法數據外,我還遇到過日期類型數據,好比2016-12-28輸入到excel中,它會默認轉換成2016/12/28,若是採用通常的getValue()方式讀取也會讀取到錯誤的數據,PHPExcel也提供了相應的接口getFormattedValue(),並提供了適配的識別方式PHPExcel_Shared_Date::isDateTime($cell),因此代碼就很好實現了

if (PHPExcel_Shared_Date::isDateTime($cell)) {
    $value = $cell->getFormattedValue(); 
} else {
    $value = $cell->getValue();
}

4. 讀取方法封裝

針對excel各類數據類型,咱們能夠寫一個函數,將原有的getValue()封裝一下,這樣之後就不用每次都判別一下數據類型了,目前我只遇到上面三種特殊格式,若是有新的,歡迎你們補充,封裝函數以下

function get_value_of_cell($cell) {
    if (strstr($cell->getValue(), '=')) {   
        $value = $cell->getCalculatedValue(); 
    } else if ($cell->getValue() instanceof PHPExcel_RichText) {
        $value = $cell->getValue();
    } else if (PHPExcel_Shared_Date::isDateTime($cell)) {
        $value = $cell->getFormattedValue(); 
    } else {
        $value = $cell->getValue();
    }
}

5. 導出文件在IE、360等瀏覽器中文件名中文亂碼問題

$filename = 'xxx導出表';
// 判斷若是是IE內核形式的瀏覽器採用urlencode處理文件名
if (!preg_match("/Firefox/", $_SERVER["HTTP_USER_AGENT"])) {
    $filename = urlencode($filename);
}

未完待續。。。期待你的補充和優化

相關文章
相關標籤/搜索