PHPExcel very slow - ways to improve?

后端 未结 8 1398
孤街浪徒
孤街浪徒 2020-12-07 13:28

I am generating reports in .xlsx using PHPExcel. It was okay in the initial testing stages with small data sets (tens of rows, 3 sheets), but now when using it on a real pro

8条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-07 13:50

    I ran into this issue as well. Thought I'd throw my two cents in since this question gets so many views.

    Setting Cell Values

    Instead of setting the value for each cell individually, use the fromArray() method. Taken and modified from the wiki.

    $arrayData = array(
    array(NULL, 2010, 2011, 2012),
    array('Q1',   12,   15,   21),
    array('Q2',   56,   73,   86),
    array('Q3',   52,   61,   69),
    array('Q4',   30,   32,    0),
    );
    
    $as = $objPHPExcel->getActiveSheet();
    
    $as->fromArray(
        $arrayData,  // The data to set
        NULL,        // Array values with this value will not be set
        'C3'         // Top left coordinate of the worksheet range where
                     //    we want to set these values (default is A1)
    );
    

    Styling Cells

    Static

    It is also quicker to apply the styles for a range, than to set the style for each cell individually (noticing a pattern??).

    $default_style = array(
        'font' => array(
            'name' => 'Verdana',
            'color' => array('rgb' => '000000'),
            'size' => 11
        ),
        'alignment' => array(
            'horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
            'vertical' => \PHPExcel_Style_Alignment::VERTICAL_CENTER
        ),
        'borders' => array(
            'allborders' => array(
                'style' => \PHPExcel_Style_Border::BORDER_THIN,
                'color' => array('rgb' => 'AAAAAA')
            )
        )
    );
    
    // Apply default style to whole sheet
    $as->getDefaultStyle()->applyFromArray($default_style);
    
    $titles = array(
        'Name',
        'Number',
        'Address',
        'Telephone'
    );
    
    $title_style = array(
        'font' => array(
            'bold' => true
        ),
        'fill' => array(
            'type' => \PHPExcel_Style_Fill::FILL_SOLID,
            'startcolor' => array('rgb' => '5CACEE')
        ),
        'alignment' => array(
            'wrap' => true
        )
    );
    
    $as->fromArray($titles, null, 'A1'); // Add titles
    
    $last_col = $as->getHighestColumn(); // Get last column, as a letter
    
    // Apply title style to titles
    $as->getStyle('A1:'.$last_col.'1')->applyFromArray($title_style);
    

    Dynamically

    I use PHPExcel to check the data given in the spreadsheet with the current data in the database. Since each cell is checked individually, I put the styles in an array (null for no style), and used the loop below to get the range of cells to apply the style to.

    /*
     * $row is previously set in a loop iterating through each 
     *     row from the DB, which is equal to a spreadsheet row.
     * $styles = array(0 => 'error', 1 => 'error', 2 => null, 3 => 'changed', ...);
     */
    $start = $end = $style = null;
    foreach ($styles as $col => $s) {
        if (!$style && !$s) continue;
        if ($style === $s) {
            $end = $col;
        } else {
            if ($style) {
                $array = null;
                switch ($style) {
                    case 'changed':
                        $array = $this->changed_style;
                        break;
                    case 'error':
                        $array = $this->error_style;
                        break;
                    case 'ignored':
                        $array = $this->ignored_style;
                        break;
                }
                if ($array) { 
                    $start = \PHPExcel_Cell::stringFromColumnIndex($start);
                    $end = \PHPExcel_Cell::stringFromColumnIndex($end);
                    $as->getStyle($start.$row.':'.$end.$row)->applyFromArray($array);
                }
            }
            $start = $end = $col;
            $style = $s;
        }
    } 
    

提交回复
热议问题