php - 在 Symfony2 中使用 PHPExcel 读取 Excel 文件,编辑一个单元格的内容然后保存到数据库

标签 php symfony phpexcel

我构建了一个系统,客户端使用电子表格将数据上传到其中。它使用的是 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 Fatal error: Cannot use object of type PHPExcel_Cell as array

如有任何帮助,我们将不胜感激。

最佳答案

是的,$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),因此最好获取原始值 (123456.789) 对所有非日期值使用 getValue() 而不是 getFormattedValue(),否则在尝试插入格式化值时,您的 SQL 可能会出现错误数据库表中的 FLOAT 或 INTEGER 列中的数千个分隔符

关于php - 在 Symfony2 中使用 PHPExcel 读取 Excel 文件,编辑一个单元格的内容然后保存到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27876732/

相关文章:

php - 仅增加一个 PHP 页面的 Max_input_vars 限制

forms - 如何使用 EntityType 字段对 Symfony 4 表单进行单元测试

php - 使用原则存储序列化对象

symfony - silex 中的模块权限与角色权限

PHPExcel 创建 XLS 过载内存

php - 无法使用 PHP 将 JSON 文件中的数据添加到 MYSQL 数据库

php - 在php while循环中显示js

javascript - 我正在使用 Laravel 5.4 : and js not loading in blade during editing

php - 将 PHPEXCEL 与 SQLSRV 结合使用

PHPExcel 填充重音为假