使用 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;
    }
}