120

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

// 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');

4

17 回答 17

223

如果将列设置为 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-05-26T17:46:38.067 回答
62

如果您需要在多张工作表上执行此操作,并且每张工作表中的多列,那么您可以通过以下方式迭代所有这些:

// 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);
    }
}
于 2014-10-06T10:58:35.553 回答
29

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

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

希望这可以帮助 ;)

于 2014-07-07T12:19:51.020 回答
19
for ($i = 'A'; $i !=  $objPHPExcel->getActiveSheet()->getHighestColumn(); $i++) {
    $objPHPExcel->getActiveSheet()->getColumnDimension($i)->setAutoSize(TRUE);
}
于 2016-04-28T19:46:50.023 回答
14

不要使用 range() 它不会超出 Z 列。

只需使用:

$sheet = $spreadsheet->getActiveSheet();
foreach ($sheet->getColumnIterator() as $column) {
    $sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
}

在写入数据后执行此操作,以便列迭代器知道要迭代多少列。

于 2020-09-03T22:04:41.427 回答
11

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

$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 );
}
于 2014-08-04T11:00:49.243 回答
9

for 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);
}
于 2018-12-04T06:40:08.583 回答
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);
    }
}
于 2016-09-20T11:58:38.357 回答
4

万一有人在找这个。

下面的解决方案也适用于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)- 获取包含数据的最高工作表行。

于 2017-11-04T18:17:57.293 回答
3
// Auto-size columns for all worksheets
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
    foreach ($worksheet->getColumnIterator() as $column) {
        $worksheet
            ->getColumnDimension($column->getColumnIndex())
            ->setAutoSize(true);
    } 
}
于 2019-11-07T15:17:59.590 回答
2
foreach(range('B','G') as $columnID)
{
    $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setAutoSize(true);
}
于 2015-01-12T10:52:43.773 回答
2

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

知道在最后一个 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');
于 2016-03-18T12:14:40.767 回答
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”列并将自动调整大小设置为每一列。

于 2016-10-04T22:42:31.143 回答
1

您还需要确定要设置维度的列:

foreach (range('A', $phpExcelObject->getActiveSheet()->getHighestDataColumn()) as $col) {
$phpExcelObject
        ->getActiveSheet()
        ->getColumnDimension($col)
        ->setAutoSize(true);
}
于 2016-06-08T07:37:48.633 回答
0

对于 Spreedsheet + PHP 7,您必须编写而不是PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString。并且在循环中是一个错误,您<不能在此处使用<=. 否则,他会将一列过多地带入循环。

于 2016-10-19T10:37:47.560 回答
0
$col = 'A';
while(true){
    $tempCol = $col++;
    $objPHPExcel->getActiveSheet()->getColumnDimension($tempCol)->setAutoSize(true);
    if($tempCol == $objPHPExcel->getActiveSheet()->getHighestDataColumn()){
        break;
    }
}
于 2016-08-31T10:51:27.030 回答
0

试试这个,我是这样解决的。

$Sheet = $excel->getActiveSheet();
$lABC1 = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
$lABC2 = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');

for($I = 0; $I < count($lABC1); $I++):
  $Sheet->getColumnDimension($lABC1[$I])->setAutoSize(true);
  for($J = 0; $J < 6; $J++){
    $Sheet->getColumnDimension($lABC2[$J].$lABC1[$I])->setAutoSize(true);
  }
endfor;
于 2022-01-05T15:55:02.940 回答