【问题标题】:PHPExcel auto size column widthPHPExcel自动调整列宽
【发布时间】:2013-05-21 15:28:03
【问题描述】:

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

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

【问题讨论】:

    标签: php resize size phpexcel


    【解决方案1】:

    如果将列设置为 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()),否则它将不存在(节省内存)。

    【讨论】:

    • 非常感谢。有用。它不计算从粗体字体创建的额外间距,尽管这是预期的(我在某处读过它)。您能否更新您的答案以将其也包含在内?
    • 如果您需要粗体或斜体等字体样式的精确度,那么您需要使用 PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT,但它会慢很多
    • 没关系,我不在乎。虽然我不知道该怎么做。我正在使用 Test 文件夹中的 01simple-download-xls.php。我在哪里添加该行?对不起,我的完全noobness。我刚刚开始玩它。
    • 另外,如果您不想通过列字母而是索引进行迭代,则可以使用静态方法 PHPExcel_Cell::stringFromColumnIndex($columnIndex) 来获取列字母
    • @MarkBaker 是否有任何方法可用于处理单个语句,以便我们可以设置列表中给定的列的宽度。目前我正在使用 $activeSheetObj->getColumnDimension('G')->setWidth(35);列表中的列可以是任意顺序。
    【解决方案2】:

    如果您需要在多张工作表和每张工作表中的多列上执行此操作,您可以通过以下方式遍历所有表格:

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

    【讨论】:

    • 这是更好的解决方案,因为它不需要特别考虑 Z 之后的列。
    • 我可以确认这个答案在 PhpSpreadSheet 中也可以完美运行。非常感谢!
    • 使用$worksheet->getColumnIterator() 来简化这里的事情。参考我的回答
    【解决方案3】:

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

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

    希望这会有所帮助;)

    【讨论】:

    • 这仅在 Z 之前有效,因为range('A', 'AB') 只会返回一个名为“A”的项目。所以在这种情况下使用range() 不是一个好主意!
    • 这可行: for ($i = 'A'; $i != $phpExcelObject->getActiveSheet()->getHighestColumn(); $i++) { $worksheet->getColumnDimension($i )->setAutoSize(TRUE); }
    • 不要使用这个。请参阅我使用 $sheet->getColumnIterator() 的答案
    【解决方案4】:
    for ($i = 'A'; $i !=  $objPHPExcel->getActiveSheet()->getHighestColumn(); $i++) {
        $objPHPExcel->getActiveSheet()->getColumnDimension($i)->setAutoSize(TRUE);
    }
    

    【讨论】:

    • 很好的答案,但应该是$i <= $objPHPExcel->getActiveSheet()->getHighestColumn() 否则最后一列不会调整大小
    【解决方案5】:

    不要使用 range() 它不会在 Z 列之外工作。

    简单使用:

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

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

    【讨论】:

      【解决方案6】:

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

      $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 );
      }
      

      【讨论】:

      • 请在您的答案周围添加一些上下文,以解释它如何解决问题
      【解决方案7】:

      对于php电子表格:

      $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);}
      • @WesleyAbbenhuis 您的评论仅在不超过 26 列时有效。例如,当最高列为:'AH' 时,范围函数将无法正常工作。
      【解决方案8】:

      此代码 sn-p 将自动调整所有工作表中包含数据的所有列的大小。无需使用 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);
          }
      }
      

      【讨论】:

        【解决方案9】:

        万一有人在找这个。

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

        【讨论】:

          【解决方案10】:
          foreach(range('B','G') as $columnID)
          {
              $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setAutoSize(true);
          }
          

          【讨论】:

            【解决方案11】:

            如果您尝试使用 for ($col = 2; $col &lt;= '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”列并将自动调整大小设置为每一列。

            【讨论】:

              【解决方案12】:
              // Auto-size columns for all worksheets
              foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
                  foreach ($worksheet->getColumnIterator() as $column) {
                      $worksheet
                          ->getColumnDimension($column->getColumnIndex())
                          ->setAutoSize(true);
                  } 
              }
              

              【讨论】:

                【解决方案13】:

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

                知道在最后一个 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');
                

                【讨论】:

                  【解决方案14】:

                  您还需要识别列来设置维度:

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

                  【讨论】:

                    【解决方案15】:
                    $col = 'A';
                    while(true){
                        $tempCol = $col++;
                        $objPHPExcel->getActiveSheet()->getColumnDimension($tempCol)->setAutoSize(true);
                        if($tempCol == $objPHPExcel->getActiveSheet()->getHighestDataColumn()){
                            break;
                        }
                    }
                    

                    【讨论】:

                    • 请重新格式化您的答案并考虑这一点:好的答案将始终解释所做的工作以及以这种方式完成的原因,而不仅仅是为了OP,但对于 SO 的未来访客。
                    【解决方案16】:

                    对于 Spreedsheet + PHP 7,您必须写而不是 PHPExcel_Cell::columnIndexFromString\PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString。在循环中是一个错误,您必须在&lt; 上不能与&lt;= 一起工作。否则,他会在循环中过多地占用一列。

                    【讨论】:

                      【解决方案17】:

                      试试这个,我就这样解决了。

                      $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;
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2016-01-21
                        • 2023-03-29
                        • 2012-06-11
                        • 1970-01-01
                        • 2011-03-29
                        • 2014-04-05
                        • 2018-02-02
                        相关资源
                        最近更新 更多