如何设置PHPExcel自动调整列宽

28
我正在使用PHPExcel导出数据进行下载。当打开具有大数字的单元格时,它会显示“#######”而不是数值。我尝试了对每一列使用setAutoSize(),然后调用$sheet->calculateColumnWidths(),但仍然没有改变。我在这里看到calculateColumnWidths(),@Mark Baker说“calculateColumnWidths()增加5%的值,以确保整个列都适合”。如果单元格中数字的长度超过5%,则似乎无法解决问题。 更新: 这是我的自动调整列宽函数:
   function autoFitColumnWidthToContent($sheet, $fromCol, $toCol) {
        if (empty($toCol) ) {//not defined the last column, set it the max one
            $toCol = $sheet->getColumnDimension($sheet->getHighestColumn())->getColumnIndex();
        }
        for($i = $fromCol; $i <= $toCol; $i++) {
            $sheet->getColumnDimension($i)->setAutoSize(true);
        }
        $sheet->calculateColumnWidths();
    }

你正在应用哪种自动调整大小的方法进行计算?是近似还是精确?你使用了特定的字体吗?或者加粗/斜体样式?计算出的数字有多远?也许增加10%比5%更好。 - Mark Baker
@MarkBaker,我已经更新了我的问题的示例代码。我使用了ColumnDimension类的setAutoSize()方法。 - Davuz
2个回答

29

第一个潜在问题可能是您正在使用列字母。

PHP的自增操作将使用列字母,因此如果 $i 是 'A',那么 $i++ 将给出 'B',如果 $i 是 'Z',则 $i++ 将给出 'AA';但您不能使用 <= 作为比较器,因为当作为直接比较执行时,'AA' <='Z'。

不要使用

for($i = $fromCol; $i <= $toCol; $i++) {

使用

$toCol++;
for($i = $fromCol; $i !== $toCol; $i++) {

在调用 $sheet->calculateColumnWidths() 后添加 5% 的边距,可以按照以下方法进行:

for($i = $fromCol; $i !== $toCol; $i++) {
    $calculatedWidth = $sheet->getColumnDimension($i)->getWidth();
    $sheet->getColumnDimension($i)->setWidth((int) $calculatedWidth * 1.05);
}

谢谢!我使用setWidth((int) $calculatedWidth * 1.4);来适应16位数字。它运行良好,但我仍然希望有一个自动完全计算并设置列宽的函数^^。 - Davuz
1
@Panique,这个方法对我起作用了。你可以尝试使用setWidth((int) $calculatedWidth * 1.4);,将1.4改为更大的值,比如1.6或者1.8... - Davuz
@所有人 我删除了我的评论,因为问题出在我这边。我真的很抱歉,并给你们所有人点赞。愿力量与你同在! - Sliq
在增加列宽度后,不要忘记调用->setAutoSize(false)。否则,在保存到Excel文件时,您之前设置的setAutoSize(true)将覆盖您手动设置的宽度。 - flu

0

对我来说,这些建议都没有起作用,所以我进行了手动计算(相当简单和快速)(以下是示例代码),并且完美地工作了(请注意字体/样式是默认的,但很容易调整为其他字体或样式)。

foreach((array)$data as $sheet_data)
{
    $maxwidth = array( );
    $objPHPExcel->setActiveSheetIndex( $i++ );
    $sheet = $objPHPExcel->getActiveSheet( );

    if ( !empty($sheet_data['title']) )
        $sheet->setTitle($sheet_data['title']);

    if ( !empty($sheet_data['rows']) )
    {
        foreach((array)$sheet_data['rows'] as $row=>$cols)
        {
            foreach((array)$cols as $col=>$val)
            {
                $p = strpos($col,':');
                if ( false !== $p )
                {
                    // range
                    $range = $col; $xy = substr( $col, 0, $p );
                    $col = substr($xy,0,-1);

                    // estimate maximum column width by number of characters
                    $w = mb_strlen( $val );
                    if ( !isset($maxwidth[$col]) ) $maxwidth[$col] = $w;
                    elseif ( $w > $maxwidth[$col] ) $maxwidth[$col] = $w;

                    $sheet->mergeCells( $range );
                    $sheet->setCellValue( $xy, $val );
                    $sheet->getStyle( $range )
                            ->getAlignment( )
                            ->setHorizontal( PHPExcel_Style_Alignment::HORIZONTAL_CENTER )
                            ->setVertical( PHPExcel_Style_Alignment::VERTICAL_CENTER )
                    ;
                }
                else
                {
                    $xy = $col.$row;

                    // estimate maximum column width by number of characters
                    $w = mb_strlen( $val );
                    if ( !isset($maxwidth[$col]) ) $maxwidth[$col] = $w;
                    elseif ( $w > $maxwidth[$col] ) $maxwidth[$col] = $w;

                    $sheet->setCellValue( $xy, $val );
                    $sheet->getStyle( $xy )
                            ->getAlignment( )
                            ->setHorizontal( PHPExcel_Style_Alignment::HORIZONTAL_CENTER )
                            ->setVertical( PHPExcel_Style_Alignment::VERTICAL_CENTER )
                    ;
                }
            }
        }
    }
    // autosize columns based on calculation + some padding
    foreach($maxwidth as $col=>$width)
    {
        $sheet->getColumnDimension( $col )->setAutoSize( false );
        $sheet->getColumnDimension( $col )->setWidth( (int)($width * 1.2) ); // add padding as well
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接