關於PHPExcel設置單元格寬度的問題,原類中自帶 setAutoSize 方法可以設置 $_autoSize 屬性 , 選擇是否適應一列最大寬度 , 默認值fasle;
1 $objPHPExcel = new PHPExcel(); 2 $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); 3 4 ... 5 6 $objPHPExcel -> getActiveSheet() -> getColumnDimension(PHPExcel_Cell::stringFromColumnIndex(0)) -> setAutoSize(true);
原理是循環遍歷計算所有單元格寬度 , 比較得到最大值作為該列寬度;
實際應用發現這樣生成得Excel並不是特別美觀 , 比如說列最長內容比該列標題要長的多時 , 標題行就會產生大量空白。由此想出兩種解決方案:
- 根據標題行 ( 某一行 ) 內容長設置寬度;
- 自動適應基礎上添加規則,遍歷得到的最大寬度不能超過標題寬度得n倍;
------------------------------------------------------------------------- 直接貼代碼 -------------------------------------------------------------------------
第一種方案需要擴展兩個文件
文件一:PHPExcel \ Worksheet \ ColumnDimension.php
1 //添加私有屬性 $_relySize 2 3 /** 4 * Rely size? 5 * 6 * @var bool 7 */ 8 9 private $_relySize = false; 10 11 //添加獲取 $_relySize 的方法 12 13 /** 14 * Get Auto Size 15 * 16 * @return bool 17 */ 18 19 public function getRelySize() { 20 return $this->_relySize; 21 } 22 23 //添加設置 $_relySize 的方法 24 25 /** 26 * Get Auto Size 27 * 28 * @param bool $pValue 29 * @return PHPExcel_Worksheet_ColumnDimension 30 */ 31 32 public function setRelySize($pValue = false) { 33 $this->_relySize = (int) $pValue; 34 return $this; 35 }
文件二:PHPExcel \ Worksheet.php — 找到 calculateColumnWidths 方法修改如下
/** * Calculate widths for auto-size columns * * @param boolean $calculateMergeCells Calculate merge cell width * @param number $row Calculate merge cell width * @return PHPExcel_Worksheet; */ public function calculateColumnWidths($calculateMergeCells = false) { // initialize $autoSizes array $autoSizes = array(); $relySizes = array(); //$this->getColumnDimensions() //獲取所有列 foreach ($this->getColumnDimensions() as $colDimension) { if ($colDimension->getAutoSize()) { $autoSizes[$colDimension->getColumnIndex()] = -1; } if ($colDimension->getRelySize()) { $relySizes[$colDimension->getColumnIndex()] = $colDimension->getRelySize(); } } // There is only something to do if there are some auto-size columns if (!empty($autoSizes)) { // build list of cells references that participate in a merge $isMergeCell = array(); foreach ($this->getMergeCells() as $cells) { foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) { $isMergeCell[$cellReference] = true; } } // loop through all cells in the worksheet foreach ($this->getCellCollection(false) as $cellID) { $cell = $this->getCell($cellID); //$this->_cellCollection->getCurrentColumn() if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) { // Determine width if cell does not participate in a merge if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { // Calculated value // To formatted string $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( $cell->getCalculatedValue(), $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() ); $autoSizes[$this->_cellCollection->getCurrentColumn()] = max( (float) $autoSizes[$this->_cellCollection->getCurrentColumn()], (float)PHPExcel_Shared_Font::calculateColumnWidth( $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), $cellValue, $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), $this->getDefaultStyle()->getFont() ) ); } } } // adjust column widths foreach ($autoSizes as $columnIndex => $width) { if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth(); $this->getColumnDimension($columnIndex)->setWidth($width); } } if (!empty($relySizes)) { $isMergeCell = array(); foreach ($this->getMergeCells() as $cells) { foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) { $isMergeCell[$cellReference] = true; } } foreach ($relySizes as $col => $value) { $cell = $this->getCell($col.$value); if (isset($relySizes[$this->_cellCollection->getCurrentColumn()])) { if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { $cellValue = PHPExcel_Style_NumberFormat::toFormattedString($cell->getCalculatedValue(), $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() ); $relySizes[$this->_cellCollection->getCurrentColumn()] = (float)PHPExcel_Shared_Font::calculateColumnWidth($this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), $cellValue, $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), $this->getDefaultStyle()->getFont()) * 2; } } } foreach ($relySizes as $columnIndex => $width) { if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth(); $this->getColumnDimension($columnIndex)->setWidth($width); } } return $this; }
執行調用
$objPHPExcel = new PHPExcel(); $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); ... //根據第一行內容設置單元格寬度 $objPHPExcel -> getActiveSheet() -> getColumnDimension(PHPExcel_Cell::stringFromColumnIndex(0)) -> setRelySize(1);
第二種方案沒有用到 , 所以沒有嘗試更改 , 如果有需求者大家可以一起討論。
以上均為個人見解 , 小弟初來乍到如有不足 , 還請多多包涵!歡迎大家發表自己的見解 , 互相學習進步!謝謝!