HotXLS Docs

大型試算表串流

概覽

將超大型試算表(例如數百萬個已填入儲存格)載入記憶體可能導致 32 位元處理序發生記憶體不足錯誤;HotXLS 提供近乎固定記憶體使用量的串流讀取器與寫入器,在活頁簿剖析期間繞過 DOM 產生

直接讀取器 API

TXLSDirectReader 類別剖析活頁簿串流時不會建立記憶體內的儲存格模型,並在遇到所選儲存格時觸發 OnSheet 與 OnCell 事件

Reader := TXLSDirectReader.Create;
try
  Reader.ParallelSheets := True;
  Reader.ParallelMaxThreads := 4;
  Reader.ParallelBufferMemoryLimit := 16 * 1024 * 1024;
  Reader.OnDimension := HandleDimension;
  Reader.OnColumn := HandleColumn;
  Reader.OnRow := HandleRow;
  Reader.OnMerge := HandleMerge;
  Reader.OnCell := HandleCell;
  Reader.ReadFile('large.xlsx');
finally
  Reader.Free;
end;

ParallelSheets 啟用每個 worker 各自的工作表填充器與 XML 讀取器,同時由呼叫執行緒按工作表與儲存格的順序發出回呼

ParallelBufferMemoryLimit 限制所有作用中 worker 排隊的原始儲存格資料總量,預設為 16 MiB;ParallelPeakBufferedBytes 則回報上次平行讀取的峰值,方便診斷與容量測試

每個作用中的工作表都會分到獨立的佇列預算,避免排在後面的工作表餓死目前正在輸出的工作表;若單一儲存格超過它的份額,會視為不可分割的資料直接放行

OnDimension、OnSheetFormat、OnColumn、OnRow、OnPane 與 OnMerge 會公開使用範圍、預設寬高、欄跨度、列高或可見性、大綱與樣式索引、窗格狀態與合併範圍,完全不必建構工作表物件

版面配置回呼是選用的,會在所選工作表的 OnCell 回呼之前,於受限記憶體的中繼資料階段執行;因此合併範圍會在合併區內的儲存格之前送達,即使 OOXML 是把 mergeCells 存在 sheetData 後面

啟用平行工作表剖析時,版面配置回呼仍留在呼叫執行緒上,並在清空 worker 佇列之前就把所選工作表處理完畢

在 OnCell 裡設定 Abort 會喚醒被阻擋的生產者與消費者,在有限的內部步驟內停止進行中的 ZIP 讀取與解壓縮,等所有 worker 收攏,並讓讀取器保持可重複使用

直接寫入器 API

TXLSDirectWriter 類別將資料列直接寫入 ZIP 檔案套件,確保產生大型資料匯出時的記憶體負荷最低

Writer := TXLSDirectWriter.Create;
try
  Writer.BeginFile('large.xlsx');
  Writer.AddSheet('Data');
  Writer.AddRow(1);
  Writer.WriteString(1, 'Quarter');
  Writer.WriteString(2, 'Revenue');
  Writer.AddComment(2, 1, 'Validated source', 'Reviewer');
  Writer.AddImageFromFile(4, 1, 8, 12, 'logo.png',
    xlsDirectImagePng, 'Company logo');
  ChartIndex := Writer.AddChart(9, 1, 18, 16,
    xlsDirectChartColumn, 'Revenue');
  Writer.AddChartSeries(ChartIndex, 'Revenue',
    'Data!$A$2:$A$5', 'Data!$B$2:$B$5');
  Writer.Close;
finally
  Writer.Free;
end;

AddComment 直接寫入傳統儲存格備註,附帶作者中繼資料與對應的 VML 備註圖形,不必載入工作表物件模型

AddImage、AddImageFromFile 與 AddImageFromStream 接受雙儲存格錨點,支援 PNG、JPEG、GIF、BMP、EMF 或 WMF 資料;檔案來源會在工作表收尾時直接流入 ZIP 條目,串流來源則只保留串流參照與記錄的位元組範圍

當 AddImageFromStream 收到 OwnsStream=True 時,寫入器會在工作表側部件定案後釋放該串流;否則呼叫方必須讓這個可定位的串流保持存活,直到下一次 AddSheet 或 Close

AddChart 與 AddChartSeries 可產生直條、長條、折線、區域、圓餅、環圈或散佈圖的 ChartML,數列可以用公式支撐;AddChartXml 則接受呼叫端提供的完整圖表部件,用於進階圖表類型與擴充

備註、繪圖錨點與圖表描述子只保留給目前的工作表;sheetData 關閉後,寫入器會依序輸出工作表關聯、備註、VML、DrawingML、媒體與 ChartML,然後在下一個工作表開始前釋放這些側通道狀態