HotXLS ドキュメント

大規模スプレッドシートのストリーミング

概要

非常に大きなスプレッドシート(例:数百万件の入力済みセル)をメモリに読み込むと、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 を有効にすると、ワーカーごとのワークシート インフレーターと XML リーダーが動き、呼び出し元スレッドがワークシート順・セル順にコールバックを発行します

ParallelBufferMemoryLimit は、アクティブなワーカー全体でキューに積まれる raw セル ペイロードの合計を制限し、既定値は 16 MiB です。ParallelPeakBufferedBytes は、診断と容量テストのために直前の並列読み取りのピークを報告します

アクティブな各ワークシートはキュー予算の独立した取り分を受け取るため、後のワークシートが現在出力中のワークシートを飢えさせることはありません。取り分より大きい 1 つのセルは、削減不可能なペイロードとして受け入れられます

OnDimension、OnSheetFormat、OnColumn、OnRow、OnPane、および OnMerge は、使用済み範囲、既定の幅と高さ、列スパン、行の高さや表示状態、アウトラインとスタイルのインデックス、ペイン状態、結合範囲を、ワークシート オブジェクトを構築せずに公開します

レイアウト コールバックはオプトインで、選択されたシートの OnCell コールバックの前に、メモリ上限付きのメタデータ パスとして実行されます。したがって、OOXML が mergeCells を sheetData の後に保存していても、結合範囲はその内部のセルより先に届きます

並列シート解析を有効にしている場合でも、レイアウト コールバックは呼び出し元スレッドで実行され、ワーカーのキューを排出する前に選択されたシート分が完了します

OnCell で Abort を設定すると、ブロックされているプロデューサーとコンシューマーが起床し、進行中の ZIP 読み取りと解凍が内部の有限ステップで停止し、すべてのワーカーがジョインされ、リーダーは再利用可能な状態のままになります

直接ライター 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 は、2 セル アンカーと PNG、JPEG、GIF、BMP、EMF、WMF のペイロードを受け付けます。ファイル ソースはシートの完了時に ZIP エントリへ直接流し込まれ、ストリーム ソースはストリーム参照と記録されたバイト範囲だけを保持します

AddImageFromStream に OwnsStream=True を渡すと、ワークシートのサイド パーツ確定後にライターがそのストリームを解放します。渡さない場合は、次の AddSheet または Close の呼び出しまで、呼び出し側がシーク可能なストリームを生存させておく必要があります

AddChart と AddChartSeries は、数式に基づく系列を伴う縦棒、横棒、折れ線、面、円、ドーナツ、散布の ChartML を生成します。AddChartXml は、高度なグラフ ファミリーと拡張のために、呼び出し側が用意した完全なグラフ パーツをアタッチします

コメント、描画アンカー、グラフ記述子は現在のワークシートについてのみ保持されます。sheetData が閉じると、ライターはワークシート リレーションシップ、コメント、VML、DrawingML、メディア、ChartML を順番に出力し、次のワークシートが始まる前にサイドチャネル状態を解放します