Artikel Teknis

Penyimpanan Sel Row-Block dan Simpan XLSX Streamed di HotXLS

HotXLS menyimpan sel lembar kerja dalam blok 256 baris yang ringkas, menyelesaikan pemformatan baris, kolom dan persegi panjang melalui overlay interval lazy alih-alih membuat objek sel, dan men-streaming setiap baris langsung ke stream deflate paket saat menyimpan. Bersama-sama ketiga perubahan itu memutuskan profil memori workbook besar: penggunaan puncak mengikuti satu baris terbesar alih-alih ukuran XML lembar kerja lengkap

Alasan ini penting adalah bentuk yang ditemui setiap pengembang spreadsheet pada akhirnya. Seorang pengguna memformat seluruh kolom — satu klik, satu juta sel — dan object model naive menjawab dengan mengalokasikan satu juta objek sel untuk memegang satu indeks format angka. File di disk tetap kecil karena format XLSX mengekspresikannya sebagai satu entri <col>. Prosesnya tidak tetap kecil sama sekali

Kenapa memformat kolom membebani lebih banyak memori daripada mengisinya?

Karena pemformatan tidak punya data untuk membenarkan objek. Sel dengan nilai harus ada di suatu tempat. Sel yang kosong tetapi ber-style hanya ada untuk membawa indeks style, dan mematerialisasi jutaan itu adalah cara klasik aplikasi spreadsheet Delphi kehabisan ruang alamat pada file yang dibuka Excel secara instan

Overlay style interval menghilangkan kebutuhan itu. Instruksi pemformatan baris, kolom, atau persegi panjang disimpan sekali sebagai rentang plus bagian style yang dikontribusikannya, dan diselesaikan secara lazy ketika sel dalam rentang itu benar-benar diakses. Overlay bertahan dari edit struktural — menyisipkan baris di dalam blok yang terformat memindahkan interval alih-alih membangunnya kembali — dan mereka round-trip sebagai entri kolom, baris, dan sel hanya-style yang ringkas, persis seperti cara Excel menuliskannya

Diagram overlay gaya interval untuk HotXLS yang menunjukkan rentang pemformatan kolom disimpan sebagai satu record dengan bagian format yang diklaim alih-alih sejuta objek sel kosong di Delphi
Format kolom, baris, atau persegi hidup sekali sebagai record overlay interval yang hanya mengklaim bagian yang ia miliki. Style efektif dirakit secara lazy saat pertama kali sel di dalam rentang benar-benar disentuh
var
  Sheet: TXLSXWorksheet;
  State: TXLSXCellStyleState;
begin
  Sheet := Workbook.Sheets[1];
  // Indeks style berasal dari kumpulan style workbook, mis. dari sebuah sel
  // yang sudah Anda format sesuai cara Anda ingin rentang itu tampak
  State := BuildStateFromTemplateCell(Sheet.Cells.Item[1, 1]);
  // Format kolom B..D tanpa membuat satu objek sel kosong pun
  Sheet.StyleOverlays.Add(1, 2, MaxRowIndex, 4,
    [xfpNumberFormat, xfpAlignment], State);
end;

TXLSXFormatParts adalah himpunan yang memutuskan apa yang dikontribusikan overlay: xfpFont, xfpFill, xfpBorder, xfpNumberFormat, xfpAlignment dan xfpProtection. Menyebutkan hanya bagian yang Anda maksud adalah apa yang memungkinkan overlay berlapis dengan masuk akal — overlay kolom yang menyediakan format angka tidak bertentangan dengan overlay baris yang menyediakan fill, karena tidak satupun mengklaim bagian yang lain

Apa yang diberikan blok 256 baris kepada Anda

Lokalitas. Sel disimpan dalam blok 256 baris dengan handle publik stabil, diserialisasi row-major, sehingga menulis lembar kerja menelusuri memori dalam urutan ia akan memancarkan byte alih-alih mengejar pointer di heap. Handle stabil penting untuk permukaan API: handle yang dipegang pemanggil tetap valid melintasi reorganisasi internal yang dilakukan layout blok, yang membuat representasi ringkas menjadi detail implementasi alih-alih perubahan breaking

Diagram penyimpanan blok baris yang menunjukkan sel worksheet HotXLS disimpan dalam blok 256-baris tetap dengan handle Delphi stabil dan serialisasi baris-utama ke stream deflate XLSX
Sel duduk di blok 256 baris tetap yang hanya mengalokasikan baris terisi dan diserialisasi dalam urutan yang sama dengan byte meninggalkan proses. Handle publik selamat dari reorganisasi internal, sehingga layout blok tetap tak terlihat bagi pemanggil

Kompaksi style pool berjalan di sampingnya. Sebelum setiap simpan, font, fill, border, format angka, alignment dan protection yang tidak direferensikan sel mana pun dijatuhkan. Workbook berumur panjang mengakumulasi record style tidak terreferensi seperti dokumen berumur panjang mengakumulasi style tidak terpakai, dan workbook yang telah diedit pengguna selama satu jam dapat membawa ratusan dari mereka ke file yang tidak akan pernah dibaca siapa pun

Simpan row-streamed, dan kapan tidak berlaku

Dengan StreamingWrite diaktifkan — default — setiap baris lembar kerja ditulis langsung ke stream deflate paket. Alternatif, yang adalah apa yang dimatikan flag itu, membangun XML lembar kerja lengkap lebih dulu dan mengompresnya setelahnya, sehingga memori puncak berskala dengan seluruh sheet. Streaming membuatnya berskala dengan satu baris

Shared string dan part tambahan mengikuti disiplin yang sama melalui satu serializer UTF-8 yang dapat digunakan kembali yang memancarkan entri satu per satu, membatasi memori puncak oleh entri tunggal terbesar alih-alih seluruh part. Itu mencakup tabel shared string dan record pivot, yang pada workbook analitik lebar sering lebih besar daripada lembar kerja individual mana pun

var
  Workbook: TXLSXWorkbook;
begin
  Workbook := TXLSXWorkbook.Create;
  try
    Workbook.Open('ledger-2026.xlsx');
    // StreamingWrite default ke True; matikan hanya ketika langkah hilir
    // membutuhkan seluruh XML worksheet ada sebelum kompresi
    Workbook.StreamingWrite := True;
    Workbook.SaveAs('ledger-2026-out.xlsx');
  finally
    Workbook.Free;
  end;
end;

Biarkan aktif kecuali Anda punya alasan konkret untuk tidak. Jalur non-streaming ada untuk kasus di mana sesuatu yang lain dalam pipeline membutuhkan XML yang dirakit, dan membayarnya secara default adalah membayar untuk kasus yang tidak pernah dijumpai sebagian besar aplikasi

Bagaimana mengetahui apakah overlay benar-benar digunakan

Pantau jumlah sel, bukan grafik memori. Jika lembar kerja melaporkan jumlah sel fisik yang masuk akal setelah Anda menerapkan pemformatan luas, overlay melakukan tugasnya. Jika jumlah melompat sebesar rentang yang terformat, sesuatu dalam jalur kode mematerialisasi sel — biasanya loop yang membaca setiap sel dalam rentang untuk memeriksa stylenya, yang memaksa resolusi satu sel pada satu waktu dan menggagalkan seluruh susunan

Diagram StreamingWrite yang membandingkan streaming deflate per baris di HotXLS dengan merakit seluruh XML worksheet dalam memori sebelum kompresi di Delphi
Dengan StreamingWrite aktif, setiap baris mengalir langsung ke deflate stream paket dan memori puncak mengikuti satu baris. Mematikan flag lebih dulu merakit seluruh XML worksheet, yang menskalakan memori puncak dengan sheet penuh

Selesaikan style ketika Anda membutuhkan format efektif satu sel. Jangan selesaikan style untuk satu juta sel untuk mengetahui bahwa kolom punya format angka; tanyakan ke overlay. Aturan yang sama berlaku untuk penulisan: tetapkan nilai ke sel yang memiliki nilai, dan biarkan pemformatan tetap menjadi interval

Ke mana memori yang tersisa pergi

Setelah sel dan style ringkas, konsumen terbesar berikutnya pada workbook besar adalah tabel shared string dan part satelit apa pun yang dibawa file — pivot cache, drawing, XML yang dipertahankan dari part yang tidak dimodelkan object model. Itu punya strategi sendiri, dan jawaban yang jujur adalah tidak ada satu pengaturan yang menyelesaikan semuanya sekaligus

Jika bottleneck Anda adalah membuka alih-alih menyimpan, pemuatan selektif adalah tuasnya: panduan pemuatan hanya-metadata dan selektif lembar kerja membahas membaca workbook tanpa membayar untuk sheet yang tidak akan Anda sentuh. Untuk throughput jalur baca pada file yang sangat besar, lihat catatan tentang parsing XLSX paralel dan memory allocator, dan untuk beban kerja hanya-output yang sama sekali tidak membutuhkan object model, streaming writes untuk pekerjaan batch server biasanya lebih cocok daripada tuning apa pun di sini

HotXLS membaca dan menulis XLS dan XLSX dari kode Delphi dan C++Builder native tanpa instalasi Excel dan tanpa OLE automation, yang membuat karakteristik memori ini dapat diamati dan dikendalikan sejak awal — halaman komponen spreadsheet HotXLS mencantumkan format dan versi RAD Studio yang didukung