在 Symfony2 中使用 PHPExcel 读取 Excel 文件,编辑一个单元格的内容然后保存到数据库
Read Excel file using PHPExcel in Symfony2, edit contents of one cell then save to database
我建立了一个系统,客户端可以使用电子表格向其上传数据。它使用的是 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
) 23=] 而不是 getFormattedValue()
用于所有非日期值,否则当您尝试将带有千位分隔符的格式化值插入数据库中的 FLOAT 或 INTEGER 列时,您的 SQL 可能会出错 table
我建立了一个系统,客户端可以使用电子表格向其上传数据。它使用的是 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
) 23=] 而不是 getFormattedValue()
用于所有非日期值,否则当您尝试将带有千位分隔符的格式化值插入数据库中的 FLOAT 或 INTEGER 列时,您的 SQL 可能会出错 table