使用 PHPSpreadsheet 时将 Excel 文件转换为数组,同时保留格式
Convert Excel file to array while preseerving formatting when using PHPSpreadsheet
无论我做什么,当我将数据转换为数组时,我的数组都没有保留单元格值格式。
如何最好将格式转换为HTML?
<?php
namespace App\Service;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use PhpOffice\PhpSpreadsheet\IOFactory as ExcelFactory;
class ExcelService
{
public function getArray(UploadedFile $uploadedFile): array
{
$path = \sprintf('%s/%s', $uploadedFile->getPath(), $uploadedFile->getFilename());
$reader = ExcelFactory::createReaderForFile($path);
// assure that we are reading styling as well as data
$reader->setReadDataOnly(false);
$spreadsheet = $reader->load($path);
$sheet = $spreadsheet->getActiveSheet();
$maxCol = $sheet->getHighestDataColumn();
$maxRow = $sheet->getHighestDataRow();
$colAlpha = \range('A', $maxCol);
$colRange = \count($colAlpha);
$array = [];
for ($indexRow = 0; $indexRow <= $maxRow; $indexRow++) {
for ($indexCol = 0; $indexCol < $colRange; $indexCol++) {
$cellCoords = \sprintf('%s%d', $colAlpha[$indexCol], $indexRow + 1);
$cellObject = $sheet->getCell($cellCoords);
$cellValue = \trim((string) $cellObject->getValue());
$array[$indexRow][$indexCol] = $cellValue;
}
}
return $array;
}
}
看起来像将电子表格转换为 HTML 文件,并通过 DOMDocument 解析器读取它现在对我有用。
<?php
namespace App\Service;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use PhpOffice\PhpSpreadsheet\IOFactory as ExcelFactory;
use DOMDocument;
use DOMXPath;
class ExcelService
{
public function getArray(UploadedFile $uploadedFile): array
{
$path = \sprintf('%s/%s', $uploadedFile->getPath(), $uploadedFile->getFilename());
$excelReader = ExcelFactory::createReaderForFile($path);
$excelSpreadSheet = $excelReader->load($path);
// save spreadsheet as HTML file as we cannot access cell value formatting directly as HTML
$htmlPath = \tempnam(\sys_get_temp_dir(), 'temp_html');
$htmlWriter = new Html($excelSpreadSheet);
$htmlWriter->save($htmlPath);
return $this->getFileData($htmlPath);
}
private function getFileData(string $path): array
{
$data = [];
$contents = \file_get_contents($path);
$dom = new DOMDocument();
$dom->loadHTML($contents);
$xpath = new DOMXPath($dom);
$tables = $xpath->query('//table');
foreach ($tables as $indexTable => $table) {
$rows = $xpath->query(\sprintf('%s//tr', $table->getNodePath()));
foreach ($rows as $indexRow => $row) {
$columns = $xpath->query(\sprintf('%s/td', $row->getNodePath()));
foreach ($columns as $indexColumn => $column) {
$doc = $column->ownerDocument;
$value = '';
foreach ($column->childNodes as $n) {
$value .= $doc->saveHTML($n);
}
$data[$indexTable][$indexRow][$indexColumn] = $value;
}
}
}
return $data;
}
}
无论我做什么,当我将数据转换为数组时,我的数组都没有保留单元格值格式。
如何最好将格式转换为HTML?
<?php
namespace App\Service;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use PhpOffice\PhpSpreadsheet\IOFactory as ExcelFactory;
class ExcelService
{
public function getArray(UploadedFile $uploadedFile): array
{
$path = \sprintf('%s/%s', $uploadedFile->getPath(), $uploadedFile->getFilename());
$reader = ExcelFactory::createReaderForFile($path);
// assure that we are reading styling as well as data
$reader->setReadDataOnly(false);
$spreadsheet = $reader->load($path);
$sheet = $spreadsheet->getActiveSheet();
$maxCol = $sheet->getHighestDataColumn();
$maxRow = $sheet->getHighestDataRow();
$colAlpha = \range('A', $maxCol);
$colRange = \count($colAlpha);
$array = [];
for ($indexRow = 0; $indexRow <= $maxRow; $indexRow++) {
for ($indexCol = 0; $indexCol < $colRange; $indexCol++) {
$cellCoords = \sprintf('%s%d', $colAlpha[$indexCol], $indexRow + 1);
$cellObject = $sheet->getCell($cellCoords);
$cellValue = \trim((string) $cellObject->getValue());
$array[$indexRow][$indexCol] = $cellValue;
}
}
return $array;
}
}
看起来像将电子表格转换为 HTML 文件,并通过 DOMDocument 解析器读取它现在对我有用。
<?php
namespace App\Service;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use PhpOffice\PhpSpreadsheet\IOFactory as ExcelFactory;
use DOMDocument;
use DOMXPath;
class ExcelService
{
public function getArray(UploadedFile $uploadedFile): array
{
$path = \sprintf('%s/%s', $uploadedFile->getPath(), $uploadedFile->getFilename());
$excelReader = ExcelFactory::createReaderForFile($path);
$excelSpreadSheet = $excelReader->load($path);
// save spreadsheet as HTML file as we cannot access cell value formatting directly as HTML
$htmlPath = \tempnam(\sys_get_temp_dir(), 'temp_html');
$htmlWriter = new Html($excelSpreadSheet);
$htmlWriter->save($htmlPath);
return $this->getFileData($htmlPath);
}
private function getFileData(string $path): array
{
$data = [];
$contents = \file_get_contents($path);
$dom = new DOMDocument();
$dom->loadHTML($contents);
$xpath = new DOMXPath($dom);
$tables = $xpath->query('//table');
foreach ($tables as $indexTable => $table) {
$rows = $xpath->query(\sprintf('%s//tr', $table->getNodePath()));
foreach ($rows as $indexRow => $row) {
$columns = $xpath->query(\sprintf('%s/td', $row->getNodePath()));
foreach ($columns as $indexColumn => $column) {
$doc = $column->ownerDocument;
$value = '';
foreach ($column->childNodes as $n) {
$value .= $doc->saveHTML($n);
}
$data[$indexTable][$indexRow][$indexColumn] = $value;
}
}
}
return $data;
}
}