PHPExcel自动调整列宽


100

我正在尝试自动调整工作表的列大小。我正在写文件,最后我尝试调整所有列的大小。

// Add some data
$objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('B1', 'test1111111111111111111111')
            ->setCellValue('C1', 'test1111111111111')
            ->setCellValue('D1', 'test1111111')
            ->setCellValue('E1', 'test11111')
            ->setCellValue('F1', 'test1')
            ->setCellValue('G1', 'test1');

foreach($objPHPExcel->getActiveSheet()->getColumnDimension() as $col) {
    $col->setAutoSize(true);
}
$objPHPExcel->getActiveSheet()->calculateColumnWidths();

上面的代码不起作用。不更改列大小以适合文本

更新 我正在使用的作家$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Answers:


195

如果将列设置为AutoSize,PHPExcel会尝试根据列的计算值(基于任何公式的结果)以及格式掩码(例如千位分隔符)添加的任何其他字符来计算列宽。

默认情况下,这是estimated宽度:使用GD时,可以使用一种更准确的计算方法,该方法还可以处理字体样式功能(例如粗体和斜体);但这是一个很大的开销,因此默认情况下将其关闭。您可以使用以下方法启用更准确的计算

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

但是,自动调整大小并不适用于所有Writer格式...例如CSV。您没有提及您正在使用的作家。

但是,您还需要标识列以设置尺寸:

foreach(range('B','G') as $columnID) {
    $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)
        ->setAutoSize(true);
}

$objPHPExcel->getActiveSheet()->getColumnDimension() 需要一个列ID。

$objPHPExcel->getActiveSheet()->getColumnDimensions()将返回所有已定义列维记录的数组;但是除非明确创建了列维记录(可能是通过加载模板或通过手动调用getColumnDimension()),否则该记录将不存在(保存内存)。


非常感谢。有用。尽管可以预期,但它不会计算从粗体字体创建的额外间距(我已经在某处阅读了它)。您能否更新您的答案以使其包含其中?
2013年

1
如果您需要使用粗体或斜体等字体风格的精度,则需要使用PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT,但速度要慢得多
Mark Ba​​ker

没关系,我不在乎。虽然我不知道该怎么做。我正在使用Test文件夹中的01simple-download-xls.php。我在哪里添加那条线?对不起,我完全呆了。我刚刚开始玩。
Alkis Kalogeris

2
此外,如果您不想通过列字母进行迭代,而是使用索引,则可以使用静态方法PHPExcel_Cell :: stringFromColumnIndex($ columnIndex)来获取列字母
MeatPopsicle 2014年

@MarkBaker有没有可用的方法来处理单个语句,以便我们可以设置列表中给定列的宽度。目前我正在使用$ activeSheetObj-> getColumnDimension('G')-> setWidth(35); 列表中的列可以是任何顺序。
罗莎·米斯蒂卡(Ros Mystica)

55

如果您需要在多张纸上以及每张纸上的多列上执行此操作,则可以通过以下方法遍历所有这些纸:

// Auto size columns for each worksheet
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {

    $objPHPExcel->setActiveSheetIndex($objPHPExcel->getIndex($worksheet));

    $sheet = $objPHPExcel->getActiveSheet();
    $cellIterator = $sheet->getRowIterator()->current()->getCellIterator();
    $cellIterator->setIterateOnlyExistingCells(true);
    /** @var PHPExcel_Cell $cell */
    foreach ($cellIterator as $cell) {
        $sheet->getColumnDimension($cell->getColumn())->setAutoSize(true);
    }
}

7
这是更好的解决方案,因为对于经过Z
Anthony

2
我可以确认此答案在PhpSpreadSheet中也可以正常使用。万分感谢!
Hissvard

23

这是基于@Mark Ba​​ker帖子的更灵活的变体:

foreach (range('A', $phpExcelObject->getActiveSheet()->getHighestDataColumn()) as $col) {
        $phpExcelObject->getActiveSheet()
                ->getColumnDimension($col)
                ->setAutoSize(true);
    } 

希望这可以帮助 ;)


14
这仅在Z之前有效,因为range('A', 'AB')它将仅返回一个名为“ A”的项目。因此,range()在这种情况下使用它不是一个好主意!
2014年

7
但这可行:for($ i ='A'; $ i!= $ phpExcelObject-> getActiveSheet()-> getHighestColumn(); $ i ++){$ worksheet-> getColumnDimension($ i)-> setAutoSize(TRUE); }
内森

14
for ($i = 'A'; $i !=  $objPHPExcel->getActiveSheet()->getHighestColumn(); $i++) {
    $objPHPExcel->getActiveSheet()->getColumnDimension($i)->setAutoSize(TRUE);
}

2
好的答案,但是应该$i <= $objPHPExcel->getActiveSheet()->getHighestColumn()否则,最后一列的大小将不会被调整
billynoah 18-3-23

10

这是如何使用工作表中所有列的示例:

$sheet = $PHPExcel->getActiveSheet();
$cellIterator = $sheet->getRowIterator()->current()->getCellIterator();
$cellIterator->setIterateOnlyExistingCells( true );
/** @var PHPExcel_Cell $cell */
foreach( $cellIterator as $cell ) {
        $sheet->getColumnDimension( $cell->getColumn() )->setAutoSize( true );
}

3
请在您的答案周围添加一些背景信息,以解释它如何解决问题
Andrew Stubbs 2014年

6

此代码段将自动调整所有工作表中包含数据的所有列的大小。无需使用activeSheet getter和setter。

// In my case this line didn't make much of a difference
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
// Iterating all the sheets
/** @var PHPExcel_Worksheet $sheet */
foreach ($objPHPExcel->getAllSheets() as $sheet) {
    // Iterating through all the columns
    // The after Z column problem is solved by using numeric columns; thanks to the columnIndexFromString method
    for ($col = 0; $col <= PHPExcel_Cell::columnIndexFromString($sheet->getHighestDataColumn()); $col++) {
        $sheet->getColumnDimensionByColumn($col)->setAutoSize(true);
    }
}

6

对于phpspreadsheet:

$sheet = $spreadsheet->getActiveSheet(); // $spreadsheet is instance of PhpOffice\PhpSpreadsheet\Spreadsheet

foreach (
    range(
         1, 
         Coordinate::columnIndexFromString($sheet->getHighestColumn(1))
    ) as $column
) {
    $sheet
          ->getColumnDimension(Coordinate::stringFromColumnIndex($column))
          ->setAutoSize(true);
}

foreach (range('A', $sheet->getHighestDataColumn()) as $column) {$sheet->getColumnDimension($column)->setAutoSize(true);}
Wesley Abbenhuis

1
@WesleyAbbenhuis您的评论将仅在不超过26列时起作用。例如,当最高的列为:“ AH”时,范围功能将无法正常工作。
Sander Van Keer

3
foreach(range('B','G') as $columnID)
{
    $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setAutoSize(true);
}

3

万一有人在找这个。

下面的分辨率也可以在PHPSpreadsheet其新版本的PHPExcel上使用。

// assuming $spreadsheet is instance of PhpOffice\PhpSpreadsheet\Spreadsheet
// assuming $worksheet = $spreadsheet->getActiveSheet();
foreach(range('A',$worksheet->getHighestColumn()) as $column) {
    $spreadsheet->getColumnDimension($column)->setAutoSize(true);
}

注意:getHighestColumn()可以替换为getHighestDataColumn()或最后一个实际列。

这些方法的作用:

getHighestColumn($row = null) -获取最高的工作表列。

getHighestDataColumn($row = null) -获取包含数据的最高工作表列。

getHighestRow($column = null) -获得最高的工作表行

getHighestDataRow($column = null) -获取包含数据的最高工作表行。


2

如果尝试使用进行迭代for ($col = 2; $col <= 'AC'; ++ $col){...},或者使用进行迭代,foreach(range('A','AC') as $col) {...}则适用于从A到Z的列,但是它无法通过Z(例如,在“ A”到“ AC”之间进行迭代)。

为了迭代传递“ Z”,您需要将列转换为整数,递增,比较并再次将其作为字符串获取:

$MAX_COL = $sheet->getHighestDataColumn();
$MAX_COL_INDEX = PHPExcel_Cell::columnIndexFromString($MAX_COL);
    for($index=0 ; $index <= $MAX_COL_INDEX ; $index++){
    $col = PHPExcel_Cell::stringFromColumnIndex($index);

    // do something, like set the column width...
    $sheet->getColumnDimension($col)->setAutoSize(TRUE);
}

这样,您就可以轻松地迭代传递“ Z”列,并将自动调整大小设置为每一列。


1

来晚了,但是在到处搜索之后,我创建了一个似乎是“一个”的解决方案。

知道在最后一个API版本上有一个列迭代器,但是不知道如何自动调整它自己的列对象,基本上,我已经创建了一个循环,从真正的第一个使用过的列到真正的最后一个使用过的列。

它去了:

//Just before saving de Excel document, you do this:

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

//We get the util used space on worksheet. Change getActiveSheet to setActiveSheetIndex(0) to choose the sheet you want to autosize. Iterate thorugh'em if needed.
//We remove all digits from this string, which cames in a form of "A1:G24".
//Exploding via ":" to get a 2 position array being 0 fisrt used column and 1, the last used column.
$cols = explode(":", trim(preg_replace('/\d+/u', '', $objPHPExcel->getActiveSheet()->calculateWorksheetDimension())));

$col = $cols[0]; //first util column with data
$end = ++$cols[1]; //last util column with data +1, to use it inside the WHILE loop. Else, is not going to use last util range column.
while($col != $end){
    $objPHPExcel->getActiveSheet()->getColumnDimension($col)->setAutoSize(true);

    $col++;
}

//Saving.
$objWriter->save('php://output');

1

您还需要标识列以设置尺寸:

foreach (range('A', $phpExcelObject->getActiveSheet()->getHighestDataColumn()) as $col) {
$phpExcelObject
        ->getActiveSheet()
        ->getColumnDimension($col)
        ->setAutoSize(true);
}

1
$col = 'A';
while(true){
    $tempCol = $col++;
    $objPHPExcel->getActiveSheet()->getColumnDimension($tempCol)->setAutoSize(true);
    if($tempCol == $objPHPExcel->getActiveSheet()->getHighestDataColumn()){
        break;
    }
}

5
请重新格式化您的答案,并考虑以下问题:一个好的答案将始终对这样做的原因以及这样做的原因做出解释,这不仅适用于OP,而且适用于将来的SO访问者。
B001ᛦ16年

1

对于Spreedsheet + PHP 7,你必须写,而不是PHPExcel_Cell::columnIndexFromString\PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString。而且在循环中是一个错误,您<不能在那里使用<=。否则,他会过多地进入循环中。


1
// Auto-size columns for all worksheets
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
    foreach ($worksheet->getColumnIterator() as $column) {
        $worksheet
            ->getColumnDimension($column->getColumnIndex())
            ->setAutoSize(true);
    } 
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.