【问题标题】:Read Excel file using PHPExcel in Symfony2, edit contents of one cell then save to database在 Symfony2 中使用 PHPExcel 读取 Excel 文件,编辑一个单元格的内容然后保存到数据库
【发布时间】:2015-03-08 17:29:01
【问题描述】:

我已经构建了一个系统,客户端使用电子表格将数据上传到它。它使用的是 CSV,但其中包含的数据意味着上传不太可靠。因此,我将使用 PHPExcel 和 Symfony2 的 PHPExcel 包来读取上传的 Excel 电子表格并将这些数据插入数据库。

我在使用 PHPExcel 时遇到了两个问题。首先是上传的文件中有一个列,其中包含英国格式(DD/MM/YYYY)的日期。但是,很明显,MySQL 使用美国格式(YYYY-MM-DD)。所以我想做的是格式化一个特定的单元格以使用 YYYY-MM-DD 格式而不是 DD/MM/YYYY。

我遇到的第二个问题是,我想以最有效的方式将所有这些数据插入 MySQL 数据库。我不确定如何最好地做到这一点。我知道在使用大型电子表格时我会遇到使用 PHPExcel 的内存问题,所以我想确保尽可能高效地保存到数据库。

到目前为止,我一直专注于阅读 Excel 文件,这是我的代码:

        $objPHPExcel = $this->get('phpexcel')->createPHPExcelObject($dir.$fileName);

        $objPHPExcel->setActiveSheetIndex(0);
        $row = $objPHPExcel->getActiveSheet()->getHighestRow()+1;

        foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
                echo 'Worksheet - ' , $worksheet->getTitle();
                echo '<table>';
                foreach ($worksheet->getRowIterator() as $row) {
                        //echo '<trRow number - ' , $row->getRowIndex() , EOL;
                        echo '<tr>';

                        $cellIterator = $row->getCellIterator();
                        $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set
                        foreach ($cellIterator as $cell) {
                                if (!is_null($cell)) {
                                        echo '<td>'.$cell->getFormattedValue().'</td>';
                                }
                        }
                        echo '<tr>';
                }
                echo '</table>';
        }

在尝试格式化单个单元格时,我将代码更改为:

        $objPHPExcel = $this->get('phpexcel')->createPHPExcelObject($dir.$fileName);
        foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
                echo 'Worksheet - ' , $worksheet->getTitle();
                echo '<table>';
                foreach ($worksheet->getRowIterator() as $row) {
                        //echo '<trRow number - ' , $row->getRowIndex() , EOL;
                        echo '<tr>';

                        $cellIterator = $row->getCellIterator();
                        $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set
                        foreach ($cellIterator as $cell) {
                                if (!is_null($cell)) {
                                        echo '<td>'.$cell[0]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[1]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[2]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[3]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[4]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[5]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[6]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[7]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[8]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[9]->getFormattedValue().'</td>';
                                        echo '<td>'.date('Y-m-d', strtotime($cell[10]->getFormattedValue())).'</td>';
                                        echo '<td>'.$cell[11]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[12]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[13]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[14]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[15]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[16]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[17]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[18]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[19]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[20]->getFormattedValue().'</td>';
                                        echo '<td>'.$cell[21]->getFormattedValue().'</td>';
                                }
                        }
                        echo '<tr>';
                }
                echo '</table>';
        }

但这在 Apache2 日志中给出了以下错误:

PHP 致命错误:无法使用 PHPExcel_Cell 类型的对象作为数组

任何帮助将不胜感激。

【问题讨论】:

    标签: php symfony phpexcel


    【解决方案1】:

    是的,$cell 不是数组,它是一个对象,所以使用$cell[0] 是无效的

    替换整个代码块:

    foreach ($cellIterator as $cell) {
        if (!is_null($cell)) {
            echo '<td>'.$cell[0]->getFormattedValue().'</td>';
            echo '<td>'.$cell[1]->getFormattedValue().'</td>';
            echo '<td>'.$cell[2]->getFormattedValue().'</td>';
            echo '<td>'.$cell[3]->getFormattedValue().'</td>';
            echo '<td>'.$cell[4]->getFormattedValue().'</td>';
            echo '<td>'.$cell[5]->getFormattedValue().'</td>';
            echo '<td>'.$cell[6]->getFormattedValue().'</td>';
            echo '<td>'.$cell[7]->getFormattedValue().'</td>';
            echo '<td>'.$cell[8]->getFormattedValue().'</td>';
            echo '<td>'.$cell[9]->getFormattedValue().'</td>';
            echo '<td>'.date('Y-m-d', strtotime($cell[10]->getFormattedValue())).'</td>';
            echo '<td>'.$cell[11]->getFormattedValue().'</td>';
            echo '<td>'.$cell[12]->getFormattedValue().'</td>';
            echo '<td>'.$cell[13]->getFormattedValue().'</td>';
            echo '<td>'.$cell[14]->getFormattedValue().'</td>';
            echo '<td>'.$cell[15]->getFormattedValue().'</td>';
            echo '<td>'.$cell[16]->getFormattedValue().'</td>';
            echo '<td>'.$cell[17]->getFormattedValue().'</td>';
            echo '<td>'.$cell[18]->getFormattedValue().'</td>';
            echo '<td>'.$cell[19]->getFormattedValue().'</td>';
            echo '<td>'.$cell[20]->getFormattedValue().'</td>';
            echo '<td>'.$cell[21]->getFormattedValue().'</td>';
        }
    }
    

    foreach ($cellIterator as $cell) {
        if (!is_null($cell)) {
            if ($cell->getColumn() == 'K') {
                // The 10th column (column K) is a date that needs reformatting
                $cellValue = date('Y-m-d', strtotime($cell->getFormattedValue()));
            } else {
                 $cellValue = $cell->getFormattedValue();
            }
            echo '<td>'.$cellValue.'</td>';
        }
    }
    

    使用PHPExcel自己的日期处理方法也比依赖日期单元格的格式化值更好,所以

    $cellValue = PHPExcel_Shared_Date::ExcelToPHPObject($cell->getValue())
        ->format('Y-m-d');
    

    会比

    更清洁、更安全
    $cellValue = date('Y-m-d', strtotime($cell->getFormattedValue()));
    

    另外,如果其他列可能包含日期值,而不是检查特定列,请替换

    if ($cell->getColumn() == 'K') {
        // The 10th column (column K) is a date that needs reformatting
    

    if (PHPExcel_Shared_Date::isDateTime($cell)) {
        // Cell contains a date value that needs reformatting
    

    所以最终的结果应该是这样的:

    foreach ($cellIterator as $cell) {
        if (!is_null($cell)) {
            if (PHPExcel_Shared_Date::isDateTime($cell)) {
                // Cell contains a date value that needs reformatting
                $cellValue = PHPExcel_Shared_Date::ExcelToPHPObject($cell->getValue())
                    ->format('Y-m-d');
            } else {
                 $cellValue = $cell->getFormattedValue();
            }
            echo '<td>'.$cellValue.'</td>';
        }
    }
    

    您可能还想考虑通过设置消除if (!is_null($cell)) 测试

    $cellIterator->setIterateOnlyExistingCells(true); 
    

    最后一点,当您计划将所有这些行数据插入 MySQL 数据库时,在迭代时为行中的每个单元格构建一个数组,并在每行的末尾进行插入。 但是,由于数值的格式化值可能包括千位分隔符、货币代码等(例如$ 123,456.789),因此使用getValue() 而不是@ 来获取原始值(123456.789)可能会更好。 987654335@ 对于所有非日期值,否则在尝试将带有千位分隔符的格式化值插入数据库表中的 FLOAT 或 INTEGER 列时,您的 SQL 可能会出错

    【讨论】:

      猜你喜欢
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 2018-01-08
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多