phpspreadsheet中文文档(五)节约内存+PHPExcel迁移

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

phpspreadsheet中⽂⽂档(五)节约内存+PHPExcel迁移
2019年10⽉11⽇14:03:31
节省内存
PhpSpreadsheet在⼯作表中平均每个单元格使⽤约1k,因此⼤型⼯作簿可以迅速⽤尽可⽤内存。

单元缓存提供了⼀种机制,使PhpSpreadsheet可以将单元对象维护在较⼩的内存或⾮内存中(例如:在磁盘上,在APCu中,内存缓存或Redis中)。

这使您可以减少⼤型⼯作簿的内存使⽤量,尽管以访问单元数据的速度为代价。

默认情况下,PhpSpreadsheet将所有单元格对象保留在内存中,但是您可以通过提供⾃⼰的实现来指定替代项。

PhpSpreadsheet密钥会⾃动命名,并在使⽤后清除,因此单个缓存实例可在PhpSpreadsheet的⼏种⽤法之间共享,甚⾄与其他缓存⽤法共享。

为了使细胞缓存,您必须提供⾃⼰的实现,像这样的缓存:
$cache = new MyCustomPsr16Implementation();
\PhpOffice\PhpSpreadsheet\Settings::setCache($cache);
将为每个单独的⼯作表维护⼀个单独的缓存,并在根据您配置的设置实例化⼯作表时⾃动创建该缓存。

⼀旦开始阅读⼯作簿或创建第⼀个⼯作表,就⽆法更改配置设置。

当⼼TTL
与常见的缓存概念相反,PhpSpreadsheet数据⽆法从头开始重新⽣成。

如果存储了某些数据,但以后⽆法检索,则PhpSpreadsheet将引发异常。

这意味着存储在缓存中的数据不得由第三⽅或通过TTL机制删除。

因此,请确保TTL已停⽤或⾜够长以覆盖PhpSpreadsheet的全部⽤法。

常见⽤例
PhpSpreadsheet不随备⽤缓存实现⼀起提供。

您可以根据⾃⼰的环境选择最合适的实现。

您可以从头开始实现,也可以使⽤。

这样的库之⼀就是,它提供了多种选择。

有关详细信息,请参阅他们的⽂档,但是这⾥有⼀些建议可以帮助您⼊门。

铜铜合⾦
要求将软件包放⼊您的项⽬中:
composer require cache/simple-cache-bridge cache/apcu-adapter
⽤以下⽅式配置PhpSpreadsheet:
$pool = new \Cache\Adapter\Apcu\ApcuCachePool();
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);
\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
雷迪斯
要求将软件包放⼊您的项⽬中:
composer require cache/simple-cache-bridge cache/redis-adapter
⽤以下⽅式配置PhpSpreadsheet:
$client = new \Redis();
$client->connect('127.0.0.1', 6379);
$pool = new \Cache\Adapter\Redis\RedisCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);
\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
记忆快取
要求将软件包放⼊您的项⽬中:
composer require cache/simple-cache-bridge cache/memcache-adapter
⽤以下⽅式配置PhpSpreadsheet:
$client = new \Memcache();
$client->connect('localhost', 11211);
$pool = new \Cache\Adapter\Memcache\MemcacheCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);
\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
从PHPExcel迁移
PhpSpreadsheet通过引⼊名称空间和重命名某些类⽽引⼊了许多重⼤更改。

为了帮助您迁移现有项⽬,编写了⼀个⼯具,将对PHPExcel类的所有引⽤替换为它们的新名称。

但是,还需要进⾏⼿动更改。

⾃动化⼯具
该⼯具包含在PhpSpreadsheet中。

它从当前⽬录开始递归扫描所有⽂件和⽬录。

假设它是⽤composer安装的,则可以这样运⾏:
cd /project/to/migrate/src
/project/to/migrate/vendor/phpoffice/phpspreadsheet/bin/migrate-from-phpexcel
重要说明该⼯具将不可逆转地修改您的源代码,确保备份所有内容,并在提交前仔细检查结果。

⼿动变更
除了⾃动更改之外,还需要⼿动迁移⼀些内容。

重命名读者和作家
当使⽤IOFactory::createReader(),IOFactory::createWriter()并且IOFactory::identify(),使⽤的读/写短名称。

更改了它们以及它们相应的类,以消除歧义:
之前后
'CSV''Csv'
'Excel2003XML''Xml'
'Excel2007''Xlsx'
'Excel5''Xls'
'Gnumeric''Gnumeric'
'HTML''Html'
'OOCalc''Ods'
'OpenDocument''Ods'
'PDF''Pdf'
'SYLK''Slk'
简化的IOFactory
下列⽅法:
PHPExcel_IOFactory::getSearchLocations()
PHPExcel_IOFactory::setSearchLocations()
PHPExcel_IOFactory::addSearchLocation()
被IOFactory::registerReader()和取代IOFactory::registerWriter()。

这意味着IOFactory现在依赖于类的⾃动加载。

之前:
\PHPExcel_IOFactory::addSearchLocation($type, $location, $classname);
后:
\PhpOffice\PhpSpreadsheet\IOFactory::registerReader($type, $classname);
删除过时的东西
⼯作表:: duplicateStyleArray()
// Before
$worksheet->duplicateStyleArray($styles, $range, $advanced);
// After
$worksheet->getStyle($range)->applyFromArray($styles, $advanced); DataType :: dataTypeForValue()
// Before
DataType::dataTypeForValue($value);
// After
DefaultValueBinder::dataTypeForValue($value);
有条件的:: getCondition()
// Before
$conditional->getCondition();
// After
$conditional->getConditions()[0];
有条件的:: setCondition()
// Before
$conditional->setCondition($value);
// After
$conditional->setConditions($value);
⼯作表:: getDefaultStyle()
// Before
$worksheet->getDefaultStyle();
// After
$worksheet->getParent()->getDefaultStyle();
⼯作表:: setDefaultStyle()
// Before
$worksheet->setDefaultStyle($value);
// After
$worksheet->getParent()->getDefaultStyle()->applyFromArray([
'font' => [
'name' => $pValue->getFont()->getName(),
'size' => $pValue->getFont()->getSize(),
],
]);
⼯作表:: setSharedStyle()
// Before
$worksheet->setSharedStyle($sharedStyle, $range);
// After
$worksheet->duplicateStyle($sharedStyle, $range);
⼯作表:: getSelectedCell()
// Before
$worksheet->getSelectedCell();
// After
$worksheet->getSelectedCells();
Writer \ Xls :: setTempDir()
// Before
$writer->setTempDir();
// After, there is no way to set temporary storage directory anymore
⾃动装带器
该类PHPExcel_Autoloader已被完全删除,并由作曲家⾃动加载机制取代。

撰写PDF
PDF库必须通过composer安装。

并且以下⽅法已被删除并被替换为IOFactory::registerWriter():
PHPExcel_Settings::getPdfRenderer()
PHPExcel_Settings::setPdfRenderer()
PHPExcel_Settings::getPdfRendererName()
PHPExcel_Settings::setPdfRendererName()
之前:
\PHPExcel_Settings::setPdfRendererName(PHPExcel_Settings::PDF_RENDERER_MPDF);
\PHPExcel_Settings::setPdfRenderer($somePath);
$writer = \PHPExcel_IOFactory::createWriter($spreadsheet, 'PDF');
后:
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Mpdf');
// Or alternatively
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');
// Or alternatively
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
渲染图
为HTML或PDF输出呈现图表时,该过程也得到了简化。

并且,尽管仍然提供JpGraph⽀持,但遗憾的是它不是最新的PHP版本的最新内容,并且会⽣成各种警告。

如果您依赖此功能,请考虑为JpGraph或其他IRenderer实现提供补丁(⼀个不错的选择可能是)。

之前:
$rendererName = \PHPExcel_Settings::CHART_RENDERER_JPGRAPH;
$rendererLibrary = 'jpgraph3.5.0b1/src/';
$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
\PHPExcel_Settings::setChartRenderer($rendererName, $rendererLibraryPath);
后:
通过composer要求依赖:
composer require jpgraph/jpgraph
接着:
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
PclZip和ZipArchive
放弃了对PclZip的⽀持,⽽⽀持更完整和现代的。

因此,以下内容被删除:
PclZip
PHPExcel_Settings::setZipClass()
PHPExcel_Settings::getZipClass()
PHPExcel_Shared_ZipArchive
PHPExcel_Shared_ZipStreamWrapper
单元缓存
单元缓存已⼤量重构以利⽤。

这意味着与该功能相关的⼤多数类均已删除:
PHPExcel_CachedObjectStorage_APC
PHPExcel_CachedObjectStorage_DiscISAM
PHPExcel_CachedObjectStorage_ICache
PHPExcel_CachedObjectStorage_Igbinary
PHPExcel_CachedObjectStorage_Memcache
PHPExcel_CachedObjectStorage_Memory
PHPExcel_CachedObjectStorage_MemoryGZip
PHPExcel_CachedObjectStorage_MemorySerialized
PHPExcel_CachedObjectStorage_PHPTemp
PHPExcel_CachedObjectStorage_SQLite
PHPExcel_CachedObjectStorage_SQLite3
PHPExcel_CachedObjectStorage_Wincache
除此之外,\PhpOffice\PhpSpreadsheet::getCellCollection()更名
为\PhpOffice\PhpSpreadsheet::getCoordinates()和\PhpOffice\PhpSpreadsheet::getCellCacheController()到\PhpOffice\PhpSpreadsheet::getCellCollection()了清晰度。

请参阅以了解如何迁移。

删除有条件返回的单元格
对于以下所有⽅法,将⽆法再更改返回值的类型。

它总是返回⼯作表,⽽不返回单元格或规则:
⼯作表:: setCellValue()
⼯作表:: setCellValueByColumnAndRow()
⼯作表:: setCellValueExplicit()
⼯作表:: setCellValueExplicitByColumnAndRow()
⼯作表:: addRule()
迁移类似于:
// Before
$cell = $worksheet->setCellValue('A1', 'value', true);
// After
$cell = $worksheet->getCell('A1')->setValue('value');
标准化的样式键
⽤于样式的数组键已经过标准化,以获得更连贯的体验。

现在,它使⽤与getter和setter相同的措辞和⼤⼩写:
// Before
$style = [
'numberformat' => [
'code' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE,
],
'font' => [
'strike' => true,
'superScript' => true,
'subScript' => true,
],
'alignment' => [
'rotation' => 90,
'readorder' => Alignment::READORDER_RTL,
'wrap' => true,
],
'borders' => [
'diagonaldirection' => Borders::DIAGONAL_BOTH,
'allborders' => [
'style' => Border::BORDER_THIN,
],
],
'fill' => [
'type' => Fill::FILL_GRADIENT_LINEAR,
'startcolor' => [
'argb' => 'FFA0A0A0',
],
'endcolor' => [
'argb' => 'FFFFFFFF',
],
],
];
// After
$style = [
'numberFormat' => [
'formatCode' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE,
],
'font' => [
'strikethrough' => true,
'superscript' => true,
'subscript' => true,
],
'alignment' => [
'textRotation' => 90,
'readOrder' => Alignment::READORDER_RTL,
'wrapText' => true,
],
'borders' => [
'diagonalDirection' => Borders::DIAGONAL_BOTH,
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
],
],
'fill' => [
'fillType' => Fill::FILL_GRADIENT_LINEAR,
'startColor' => [
'argb' => 'FFA0A0A0',
],
'endColor' => [
'argb' => 'FFFFFFFF',
],
],
];
专⽤的类来操纵坐标
曾经存在于PHPExcel_Cell其中的坐标处理⽅法被提取到⼀个专⽤的新类中\PhpOffice\PhpSpreadsheet\Cell\Coordinate。

⽅法是:
absoluteCoordinate()
absoluteReference()
buildRange()
columnIndexFromString()
coordinateFromString()
extractAllCellReferencesInRange()
getRangeBoundaries()
mergeRangesInCollection()
rangeBoundaries()
rangeDimension()
splitRange()
stringFromColumnIndex()
列索引基于1
列索引现在基于1。

所以列A是index 1。

这与从1开始的⾏和为column COLUMN()返回的Excel函数⼀致。

因此,必须对代码进⾏如下修改:1A // Before
$cell = $worksheet->getCellByColumnAndRow($column, $row);
for ($column = 0; $column < $max; $column++) {
$worksheet->setCellValueByColumnAndRow($column, $row, 'value ' . $column);
}
// After
$cell = $worksheet->getCellByColumnAndRow($column + 1, $row);
for ($column = 1; $column <= $max; $column++) {
$worksheet->setCellValueByColumnAndRow($column, $row, 'value ' . $column);
}
以下所有⽅法均会受到影响:
PHPExcel_Worksheet::cellExistsByColumnAndRow()
PHPExcel_Worksheet::freezePaneByColumnAndRow()
PHPExcel_Worksheet::getCellByColumnAndRow()
PHPExcel_Worksheet::getColumnDimensionByColumn()
PHPExcel_Worksheet::getCommentByColumnAndRow()
PHPExcel_Worksheet::getStyleByColumnAndRow()
PHPExcel_Worksheet::insertNewColumnBeforeByIndex()
PHPExcel_Worksheet::mergeCellsByColumnAndRow()
PHPExcel_Worksheet::protectCellsByColumnAndRow()
PHPExcel_Worksheet::removeColumnByIndex()
PHPExcel_Worksheet::setAutoFilterByColumnAndRow()
PHPExcel_Worksheet::setBreakByColumnAndRow()
PHPExcel_Worksheet::setCellValueByColumnAndRow()
PHPExcel_Worksheet::setCellValueExplicitByColumnAndRow()
PHPExcel_Worksheet::setSelectedCellByColumnAndRow()
PHPExcel_Worksheet::stringFromColumnIndex()
PHPExcel_Worksheet::unmergeCellsByColumnAndRow()
PHPExcel_Worksheet::unprotectCellsByColumnAndRow()
PHPExcel_Worksheet_PageSetup::addPrintAreaByColumnAndRow()
PHPExcel_Worksheet_PageSetup::setPrintAreaByColumnAndRow()
删除默认值
许多⽅法的默认值在没有意义时被删除。

通常,setter⽅法不应具有默认值。

有关⽅法及其原始默认值的完整列表,请参见commit。

相关文档
最新文档