溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么用php庫(kù)boxspout解析大型Excel表格

發(fā)布時(shí)間:2021-07-23 17:34:28 來(lái)源:億速云 閱讀:217 作者:chen 欄目:編程語(yǔ)言

這篇文章主要介紹“怎么用php庫(kù)boxspout解析大型Excel表格”,在日常操作中,相信很多人在怎么用php庫(kù)boxspout解析大型Excel表格問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么用php庫(kù)boxspout解析大型Excel表格”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

PHP解析Excel有個(gè)比較有名的庫(kù)是phpoffice/phpexcel。在實(shí)際使用的過(guò)程中,遇到上萬(wàn)行的Excel時(shí),phpexcel的內(nèi)存使用量會(huì)飆升。今天我來(lái)介紹另一個(gè)高效解析Excel的PHP庫(kù)box/spout。

看官方介紹是:Read and write spreadsheet files in a fast and scalable way,可見(jiàn)這個(gè)庫(kù)在解析Excel時(shí),Excel文件的大小不會(huì)太影響內(nèi)存的使用量??梢哉f(shuō)是PHPExcel一種替代方案。

由于box/spout庫(kù)的Github主頁(yè)上的文檔鏈接已經(jīng)掛了,這里簡(jiǎn)單寫(xiě)了一個(gè)XLSX文件轉(zhuǎn)化成CSV的例子:

include 'vendor/autoload.php';
use Box\Spout\Reader\ReaderFactory;
use Box\Spout\Common\Type;

$t = time();
$reader = ReaderFactory::create(Type::XLSX);
//如果注釋掉,單元格內(nèi)的日期類(lèi)型將會(huì)是DateTime,不注釋的話(huà)Spout自動(dòng)幫你將日期轉(zhuǎn)化成string
//$reader->setShouldFormatDates(true);
$reader->open('./test.xlsx');
$iterator = $reader->getSheetIterator();
$iterator->rewind();
$sheet1 = $iterator->current();
$rowIter = $sheet1->getRowIterator();
foreach ($rowIter as $row) {
    $d = '';
    foreach ($row as $col) {
        echo $d;
        if ($col instanceof DateTime) {
            echo $col->format('Y-m-d');
        } else {
            echo $col;
        }
        $d = "\t";
    }
    echo PHP_EOL;
}
$reader->close();

使用方法還是很簡(jiǎn)潔明了的。

使用內(nèi)存緩存String字典

前面說(shuō)到box/spout在解析時(shí)消耗的內(nèi)存大小,不受Excel文件大小的影響,這是如何做到的呢?

這里簡(jiǎn)單科普一下:XLSX文件格式是符合一項(xiàng)標(biāo)準(zhǔn)的,這項(xiàng)標(biāo)準(zhǔn)叫做OOXML(https://zh.wikipedia.org/zh-cn/Office_Open_XML)。XLSX實(shí)際上就是一個(gè)Zip包,可以解壓縮出來(lái)看看其中的內(nèi)容。

XLSX表格中,如果單元格的內(nèi)容是一串字符串時(shí),實(shí)際保存的時(shí)候只保存一個(gè)stringId,字符串真正的內(nèi)容保存在一個(gè)String字典中。

在讀取XLSX文件時(shí),如果單元格是字符串,Spout就要去查詢(xún)String字典。Spout有兩種查詢(xún)方法,一是每次從文件里讀取字典的一部分查詢(xún),二是把整個(gè)字典加載到內(nèi)存里查詢(xún)。

顯然把String字典整個(gè)加載到內(nèi)存里,查詢(xún)速度最快。但Spout過(guò)于保守,很多情況下都是采用第一種查詢(xún)方式。所以稍微修改下Spout的代碼,讓Spout盡量把字典全部加載到內(nèi)存:

# Spout/Reader/XLSX/Helper/SharedStringsCaching/CachingStrategyFactory.php
class CachingStrategyFactory {
  ....
  const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000; // 改成50000
  ....
}

試驗(yàn)一個(gè)1.3w行、28列、2.8MB大小的EXCEL轉(zhuǎn)化成CSV,做個(gè)對(duì)比:

方式耗時(shí)占用內(nèi)存
字典不加載到內(nèi)存185 s1.3 MB
字典加載到內(nèi)存43 s9.4 MB

可見(jiàn)處理時(shí)間相差還是挺大的。

到此,關(guān)于“怎么用php庫(kù)boxspout解析大型Excel表格”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI