يخزّن HotXLS خلايا ورقة العمل في كتل صغيرة من 256 صفًا، ويحل تنسيق الصف والعمود والمستطيل عبر تراكبات فاصلة كسولة بدلًا من إنشاء كائنات خلية، ويُدفق كل صف مباشرة إلى دفق deflate للحزمة عند الحفظ. معًا تقرر تلك التغييرات الثلاثة ملف تعريف الذاكرة لمصنّف كبير: يتبع ذروة الاستخدام أكبر صف واحد لا حجم XML ورقة العمل الكاملة
سبب أهمية هذا شكلٌ يلتقي به كل مطوّر جداول بيانية في النهاية. يُنسِّق المستخدم عمودًا كاملًا — نقرة واحدة، مليون خلية — فيُجيب نموذج كائن ساذج بتخصيص مليون كائن خلية لحمل فهرس نمط رقمي واحد. الملف على القرص يبقى صغيرًا لأن صيغة XLSX تعبّر عن ذلك كمدخل <col> واحد. العملية لا تبقى صغيرة إطلاقًا
لماذا تكلف تنسيق عمود ذاكرة أكثر من ملئه؟
لأن التنسيق ليس له بيانات تبرر الكائن. خلية بقيمة يلزم أن تكون موجودة في مكان ما. خلية فارغة لكن مُنسَّقة موجودة فقط لحمل فهرس نمط، وتجسيد الملايين منها هو الطريقة الكلاسيكية التي ينفد فيها تطبيق Delphi لجداول البيانات من فضاء العناوين على ملف يفتحه Excel فورًا
تزيل تراكبات النمط الفاصلة الحاجة. تعليم تنسيق صف أو عمود أو مستطيل يُخزَّن مرة واحدة كنطاق زائد أجزاء النمط الذي يسهم بها، ويُحل كسولًا حين تُوصَل خلية في ذلك النطاق فعلًا. تعيش التراكبات التحريرات البنيوية — إدراج صف داخل كتلة مُنسَّقة ينقل الفاصل بدلًا من إعادة بنائه — وتذهب وتجيء كمدخلات عمود وصفق وخلايا بالنمط فقط مضغوطة، وهذا بالضبط كيف يكتبها Excel
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 المجموعة التي تقرر بماذا يسهم تراكب: xfpFont وxfpFill وxfpBorder وxfpNumberFormat وxfpAlignment وxfpProtection. تسمية الأجزاء التي تقصدها فقط ما يتيح للتراكبات أن تتطبّق بعقلانية — تراكب عمود يزوّد نمطًا رقميًا لا يصارع تراكب صف يزوّد تعبئة، لأن لا أحدهما يدّعي جزء الآخر
ما الذي يمنحك إياه كتلة الـ 256 صفًا
الموضعية. تُحفَظ الخلايا في كتل من 256 صفًا بمقابض عامة مستقرة، مُسلسَلة بالصف أساسًا، فكتابة ورقة عمل تمشي في الذاكرة بالترتيب الذي ستبعث به بايتات بدلًا من مطاردة مؤشرات عبر الكومة. المقابض المستقرة مهمة لسطح API: مقبض يحمله مستدعي يبقى صالحًا عبر إعادة التنظيم الداخلي الذي يؤديه تخطيط الكتل، وهذا ما يجعل التمثيل المضغوط تفصيل تنفيذ لا تغييرًا كاسرًا
يؤدي ضغط مجموعة الأنماط جنبًا إلى جنب. قبل كل حفظ، تُسقَط الخطوط والتعبئات والحدود والأنماط الرقمية والمحاذاة والحماية التي لا تشير إليها خلية. المصنفات طويلة العمر تتراكم سجلات أنماط غير مرجَعة كما تتراكم المستندات طويلة العمر أنماطًا غير مستخدمة، ويستطيع مصنّف حرّره مستخدم لساعة أن يحمل مئات منها إلى ملف لن يقرأها منه أحد إطلاقًا
الحفظ المتدفق بالصف، ومتى لا ينطبق
مع تفعيل StreamingWrite — الافتراضي — يُكتَب كل صف ورقة عمل مباشرة إلى دفق deflate للحزمة. البديل، وهو ما يطفئه العلم، يبني XML ورقة العمل الكامل أولًا ثم يضغطه بعدها، فيتدرج ذروة الذاكرة مع الورقة كاملة. التدفق يجعلها تتدرج مع صف واحد
تتبع السلاسل المشتركة والأجزاء المساعدة الانضباط نفسه عبر مُسلسِل UTF-8 واحد قابل لإعادة الاستخدام يُبعِث المدخلات واحدة في كل مرة، محددًا ذروة الذاكرة بأكبر مدخل واحد لا الجزء كله. هذا يغطي جدول السلاسل المشتركة وسجلات الجداول المحورية، التي على ورقة عمل تحليلية عريضة تكون غالبًا أكبر من أي ورقة عمل فردية
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;
اتركه مفعلًا ما لم يكن لديك سبب ملموس لعدم ذلك. مسار عدم التدفق موجود للحالات التي يحتاج فيها شيء آخر في خط الأنابيب XML المُجمَّع، ودفع ثمنه افتراضيًا هو الدفع لحالة لا تصطدم بها أغلب التطبيقات
كيف تعرف إن كانت التراكبات تُستخدم فعلًا
راقب عدد الخلايا، لا رسم الذاكرة. إن أبلغت ورقة عمل عن عدد مقبول من الخلايا الفيزيائية بعد تطبيق تنسيق واسع، فالتراكبات تقوم بعملها. إن قفز العدد بحجم النطاق المُنسَّق، فشيء في مسار الكود جسّد الخلايا — عادةً حلقة تقرأ كل خلية في النطاق لفحص نمطها، ما يجبر الدقة خلية تلو الأخرى ويهزم الترتيب كله
حُل نمطًا حين تحتاج تنسيق خلية فعال. لا تحل نمطًا لمليون خلية لتكتشف أن العمود لديه نمط رقمي؛ اسأل التراكب. القاعدة نفسها تنطبق على الكتابة: أسند قيمًا للخلايا ذات القيم، ودع التنسيق يبقى فاصلًا
أين تذهب الذاكرة المتبقية
حين تصبح الخلايا والأنماط مضغوطة، أكبر المستهلكين التالين على مصنّف كبير هما جدول السلاسل المشتركة وأي أجزاء تابعة يحملها الملف — ذاكرات الجداول المحورية، الرسومات، XML محفوظ من أجزاء لا ينمذجها نموذج الكائن. لتلك استراتيجياتها الخاصة، والجواب الصادق أن لا إعداد واحدًا يحلها جميعًا دفعة واحدة
إن عنق الزجاجة لديك هو الفتح لا الحفظ، فالتحميل الانتقائي هو الرافعة: يغطي شرح تحميل البيانات الوصفية فقط والانتقائي لأوراق العمل قراءة مصنّف دون دفع ثمن الأوراق التي لن تلمسها. لسرعة مسار القراءة على ملفات كبيرة جدًا، انظر ملاحظات تحليل XLSX المتوازي وموزّع الذاكرة، ولأحمال الإخراج فقط التي لا تحتاج نموذج كائن إطلاقًا، الكتابة المتدفقة لوظائف الخادم الدفعية عادةً أنسب من أي قدر من الضبط هنا
يقرأ ويكتب HotXLS ملفات XLS وXLSX من كود Delphi وC++Builder أصلي بلا تثبيت Excel وبلا أتمتة OLE، وهذا ما يجعل خصائص الذاكرة هذه قابلة للملاحظة والتحكم أصلًا — صفحة مكوّن HotXLS لجداول البيانات تسرد الصيغ المدعومة وإصدارات RAD Studio