我正在使用 PhpSpreadsheet 从本地 xlsx 文件读取特定值,但需要 510 毫秒,这太慢了。我需要它在 20 毫秒以下,类似于从 CSV 文件中读取 CSV 格式的相同数据。有什么加快代码速度的技巧吗?
<?php
require '/vendor/autoload.php'; // Include PhpSpreadsheet library
use PhpOffice\PhpSpreadsheet\IOFactory;
$xlsxFile = 'local.xlsx'; // path to XLSX file
$targetRowNumber = 302; // row number to access
$targetColumn = 3; // column number (C = 3)
try {
$trystarttime = microtime(true);
// Load the XLSX file
$spreadsheet = IOFactory::load($xlsxFile);
// Get the value of the specified cell (column 2, row 301)
$value = $spreadsheet->getActiveSheet()->getCellByColumnAndRow($targetColumn, $targetRowNumber)->getValue();
echo "Value in column $targetColumn, row $targetRowNumber: " . $value . "\n";
$tryendtime = microtime(true);
$durationInMilliseconds = (number_format(($tryendtime - $trystarttime) * 1000, 2)) . "ms to fetch the required row value" . PHP_EOL;
echo $durationInMilliseconds;
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}
?>
如果您知道文件类型,您可能可以通过直接创建(在本例中)XLSX 阅读器来赢得一些性能
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load($inputFileName);
另请参阅 readthedocs.io 上的 文档
如果您希望能够像读取纯文本 CSV 文件一样高效地加载 Xlsx 等复杂文件格式,那么请重新考虑您的假设。 话虽这么说,如果您只需要读取单个单元格值,那么您可以采取很多措施来提高性能。
ReadDataOnly
的情况下加载它。
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load($inputFileName);
如果文件有多个工作表,并且您只对其中一个工作表中的数据感兴趣,则告诉加载程序仅加载该工作表。
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setLoadSheetsOnly('Worksheet 1');
$spreadsheet = $reader->load($inputFileName);
如果您知道要读取的单元格地址(或多个地址),则使用读取过滤器仅从文件中读取这些单元格。
/** Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter */
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
public function readCell($targetColumn, $targetRowNumber, $worksheetName = '') {
if ($row == $targetRowNumber) {
if ($columnAddress == $targetColumn) {
return true;
}
}
return false;
}
}
/** Create an Instance of our Read Filter **/
$filterSubset = new MyReadFilter('C', 103);
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
/** Tell the Reader that we want to use the Read Filter **/
$reader->setReadFilter($filterSubset);
/** Load only the rows and columns that match our filter to Spreadsheet **/
$spreadsheet = $reader->load($inputFileName);
这些功能均已记录。
https://packagist.org/packages/avadim/fast-excel-reader
use \avadim\FastExcelReader\Excel;
$xlsxFile = 'local.xlsx'; // path to XLSX file
$targetRowNumber = 302; // row number to access
$targetColumn = 3; // column number (C = 3)
$cellAddress = 'C302';
try {
$trystarttime = microtime(true);
// Load the XLSX file
$excel = Excel::open($xlsxFile);
$excel->setReadArea($cellAddress);
$cells = $excel->readCells();
// Get the value of the specified cell
$value = $cells[$cellAddress];
echo "Value in $cellAddress: " . $value . "\n";
$tryendtime = microtime(true);
$durationInMilliseconds = (number_format(($tryendtime - $trystarttime) * 1000, 2)) . "ms to fetch the required row value" . PHP_EOL;
echo $durationInMilliseconds;
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}