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


    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



     
  • 相关阅读:
    分布式文件存储服务器之Minio对象存储技术参考指南
    httpClient4请求工具类实现
    xmake v2.5.9 发布,改进 C++20 模块,并支持 Nim, Keil MDK 和 Unity Build
    聊一聊Jmeter多用户token使用问题
    聊一聊Jmeter用IF控制器处理接口依赖
    SONiC架构分析
    SpringBoot
    微搭低代码能力月报:全新控制台/编辑器、集成企业微信、应用构建提速等
    微搭低代码已集成企业微信
    云开发CloudBase | 基本配置&用户邮箱登录开发
  • 原文地址:https://www.cnblogs.com/66w66/p/16422826.html
Copyright © 2020-2023  润新知