HotXLS lưu ô trang tính trong các khối 256 dòng compact, giải quyết định dạng dòng, cột và hình chữ nhật thông qua overlay khoảng lười thay vì tạo object ô, và stream từng dòng thẳng vào deflate stream của package khi lưu. Cùng nhau ba thay đổi đó quyết định hồ sơ bộ nhớ của một sổ làm việc lớn: mức dùng đỉnh theo dõi dòng đơn lớn nhất thay vì kích thước XML trang tính hoàn chỉnh
Lý do điều này quan trọng là một hình dạng mà mọi nhà phát triển bảng tính cuối cùng đều gặp. Một người dùng định dạng toàn bộ một cột — một nhấp, một triệu ô — và một object model ngây ngô đáp lại bằng cách cấp phát một triệu object ô để giữ một chỉ mục number-format. File trên đĩa vẫn nhỏ vì định dạng XLSX diễn tả điều đó như một mục <col> duy nhất. Tiến trình thì không hề nhỏ chút nào
Vì sao định dạng một cột lại tốn bộ nhớ hơn điền đầy nó?
Vì định dạng không có dữ liệu để biện minh cho object. Một ô có giá trị phải tồn tại ở đâu đó. Một ô rỗng nhưng có style chỉ tồn tại để mang một style index, và hiện thực hóa hàng triệu cái như vậy là cách kinh điển khiến một ứng dụng bảng tính Delphi cạn không gian địa chỉ trên một file mà Excel mở tức thì
Overlay khoảng style loại bỏ nhu cầu đó. Một chỉ dẫn định dạng dòng, cột hoặc hình chữ nhật được lưu một lần dưới dạng một khoảng cộng với các phần style nó đóng góp, và giải quyết lười khi một ô trong khoảng đó thực sự được truy cập. Overlay sống sót qua các sửa đổi cấu trúc — chèn một dòng vào trong một khối đã định dạng sẽ dịch khoảng thay vì dựng lại — và chúng vòng chuyến dưới dạng các mục cột, dòng và ô chỉ-style compact, đó chính xác là cách Excel ghi chúng
var
Sheet: TXLSXWorksheet;
State: TXLSXCellStyleState;
begin
Sheet := Workbook.Sheets[1];
// Style indexes come from the workbook style pools, e.g. from a cell
// you have already formatted the way you want the range to look
State := BuildStateFromTemplateCell(Sheet.Cells.Item[1, 1]);
// Format columns B..D without creating a single empty cell object
Sheet.StyleOverlays.Add(1, 2, MaxRowIndex, 4,
[xfpNumberFormat, xfpAlignment], State);
end;
TXLSXFormatParts là tập hợp quyết định một overlay đóng góp gì: xfpFont, xfpFill, xfpBorder, xfpNumberFormat, xfpAlignment và xfpProtection. Chỉ nêu tên những phần bạn định nghĩa là điều khiến overlay xếp lớp hợp lý — một overlay cột cung cấp number format không xung đột với một overlay dòng cung cấp fill, vì không bên nào tuyên bố sở hữu phần của bên kia
Khối 256 dòng mang lại cho bạn điều gì
Tính cục bộ. Ô được giữ trong các khối 256 dòng với handle công khai ổn định, tuần tự hóa theo hàng, nên ghi một trang tính duyệt bộ nhớ theo thứ tự nó sẽ phát byte thay vì đuổi theo con trỏ khắp heap. Handle ổn định quan trọng cho bề mặt API: một handle mà bên gọi giữ vẫn hợp lệ qua việc tái tổ chức nội bộ mà bố cục khối thực hiện, đó là điều khiến biểu diễn compact trở thành chi tiết hiện thực thay vì một thay đổi phá vỡ
Nén style pool chạy cùng với nó. Trước mỗi lần lưu, font, fill, border, number format, alignment và protection mà không ô nào tham chiếu sẽ bị loại bỏ. Sổ làm việc tồn tại lâu tích lũy bản ghi style không tham chiếu giống như tài liệu tồn tại lâu tích lũy style không dùng, và một sổ làm việc đã được người dùng chỉnh sửa một tiếng có thể mang hàng trăm cái như vậy vào một file mà không ai sẽ đọc chúng ra bao giờ
Lưu streaming theo dòng, và khi nào nó không áp dụng
Với StreamingWrite bật — mặc định — mỗi dòng trang tính được ghi trực tiếp vào deflate stream của package. Phương án thay thế, đó là cái cờ tắt, dựng XML trang tính hoàn chỉnh trước rồi nén sau, nên bộ nhớ đỉnh tỉ lệ với cả trang. Streaming khiến nó tỉ lệ với một dòng
Shared string và các part phụ trợ theo cùng kỷ luật qua một serializer UTF-8 tái sử dụng được phát ra từng mục một, giới hạn bộ nhớ đỉnh bởi mục đơn lớn nhất thay vì cả part. Điều đó bao phủ bảng shared string và bản ghi pivot, vốn trên một sổ làm việc phân tích rộng thường lớn hơn bất kỳ trang tính đơn lẻ nào
var
Workbook: TXLSXWorkbook;
begin
Workbook := TXLSXWorkbook.Create(nil);
try
Workbook.Open('ledger-2026.xlsx');
// StreamingWrite defaults to True; turn it off only when a downstream
// step requires the whole worksheet XML to exist before compression
Workbook.StreamingWrite := True;
Workbook.SaveAs('ledger-2026-out.xlsx');
finally
Workbook.Free;
end;
end;
Hãy để nó bật trừ khi bạn có lý do cụ thể để tắt. Đường không streaming tồn tại cho các trường hợp nơi thứ gì khác trong pipeline cần XML lắp ráp, và trả giá cho nó theo mặc định là trả giá cho một trường hợp mà hầu hết ứng dụng không bao giờ gặp
Làm sao biết overlay có thực sự được dùng?
Theo dõi số ô, không phải đồ thị bộ nhớ. Nếu một trang tính báo một số ô vật lý hợp lý sau khi bạn áp dụng định dạng rộng, overlay đang làm việc. Nếu số nhảy theo kích thước khoảng đã định dạng, có thứ gì đó trong đường dẫn mã đã hiện thực các ô — thường là một vòng lặp đọc mọi ô trong khoảng để kiểm tra style, điều ép giải pháp từng ô một và đánh bại toàn bộ sắp đặt
Giải một style khi bạn cần định dạng hiệu dụng của một ô. Đừng giải style cho một triệu ô chỉ để biết cột có một number format; hãy hỏi overlay. Cùng quy tắc áp dụng cho việc ghi: gán giá trị cho các ô có giá trị, và để định dạng vẫn là một khoảng
Nơi bộ nhớ còn lại đi về đâu
Một khi ô và style đã compact, những bên tiêu thụ lớn kế tiếp trên một sổ làm việc lớn là bảng shared string và các part vệ tinh mà file mang theo — pivot cache, drawing, XML bảo toàn từ các part mà object model không model. Mỗi cái có chiến lược riêng, và câu trả lời trung thực là không có thiết lập đơn lẻ nào giải quyết tất cả cùng lúc
Nếu nút cổ chai của bạn là mở thay vì lưu, tải chọn lọc là đòn bẩy: bài viết về tải trang tính metadata-only và chọn lọc trình bày việc đọc một sổ làm việc mà không trả giá cho các trang bạn sẽ không chạm tới. Đối với throughput đường đọc trên các file rất lớn, xem các ghi chú về phân tích XLSX song song và bộ cấp phát bộ nhớ, còn với khối công việc chỉ xuất mà không bao giờ cần object model, ghi streaming cho tác vụ hàng loạt máy chủ thường phù hợp hơn bất kỳ lượng tinh chỉnh nào ở đây
HotXLS đọc và ghi XLS và XLSX từ mã Delphi và C++Builder bản địa không cần cài Excel và không OLE automation, đó là điều khiến các đặc tính bộ nhớ này quan sát được và kiểm soát được ngay từ đầu — trang thành phần bảng tính HotXLS liệt kê các định dạng và phiên bản RAD Studio được hỗ trợ