phpspreadsheet 中文文檔(五)節約內存+PHPExcel遷移


2019年10月11日14:03:31

 

節省內存

PhpSpreadsheet在工作表中平均每個單元格使用約1k,因此大型工作簿可以迅速用盡可用內存。單元緩存提供了一種機制,使PhpSpreadsheet可以將單元對象維護在較小的內存或非內存中(例如:在磁盤上,在APCu中,內存緩存或Redis中)。這使您可以減少大型工作簿的內存使用量,盡管以訪問單元數據的速度為代價。

默認情況下,PhpSpreadsheet將所有單元格對象保留在內存中,但是您可以通過提供自己的PSR-16實現來指定替代項 PhpSpreadsheet密鑰會自動命名,並在使用后清除,因此單個緩存實例可在PhpSpreadsheet的幾種用法之間共享,甚至與其他緩存用法共享。

為了使細胞緩存,您必須提供自己的實現,像這樣的緩存:

$cache = new MyCustomPsr16Implementation(); \PhpOffice\PhpSpreadsheet\Settings::setCache($cache); 

將為每個單獨的工作表維護一個單獨的緩存,並在根據您配置的設置實例化工作表時自動創建該緩存。一旦開始閱讀工作簿或創建第一個工作表,就無法更改配置設置。

當心TTL

與常見的緩存概念相反,PhpSpreadsheet數據無法從頭開始重新生成。如果存儲了某些數據,但以后無法檢索,則PhpSpreadsheet將引發異常。

這意味着存儲在緩存中的數據不得由第三方或通過TTL機制刪除

因此,請確保TTL已停用或足夠長以覆蓋PhpSpreadsheet的全部用法。

常見用例

PhpSpreadsheet不隨備用緩存實現一起提供。您可以根據自己的環境選擇最合適的實現。您可以從頭開始實現PSR-16,也可以使用預先存在的庫

這樣的庫之一就是PHP Cache,它提供了多種選擇。有關詳細信息,請參閱他們的文檔,但是這里有一些建議可以幫助您入門。

銅銅合金

要求將軟件包放入您的項目中:

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實現提供補丁(一個不錯的選擇可能是CpChart)。

之前:

$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的支持,而支持更完整和現代的 PHP擴展ZipArchive因此,以下內容被刪除:

  • PclZip
  • PHPExcel_Settings::setZipClass()
  • PHPExcel_Settings::getZipClass()
  • PHPExcel_Shared_ZipArchive
  • PHPExcel_Shared_ZipStreamWrapper

單元緩存

單元緩存已大量重構以利用 PSR-16這意味着與該功能相關的大多數類均已刪除:

  • 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




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM