مقاله فنی

نوشتن فایل‌های XLSX منطبق با ISO 29500 Strict از دلفی

HotXLS کارپوشه‌های Open XML مطابق با ISO/IEC 29500 Strict را از دلفی و C++Builder با تنظیم یک ویژگی واحد، StrictOOXML، پیش از ذخیره‌سازی می‌نویسد. هر بخش در بسته، از xl/workbook.xml گرفته تا فایل‌های رابطه و انواع محتوا، با واژگان سخت‌گیرانه purl.oclc.org نوشته می‌شود، نه واژگان انتقالی schemas.openxmlformats.org، و ویژگی‌هایی که Strict مجاز نمی‌داند به‌جای نوشته‌شدن به هر شکل، با یک استثنای صریح رد می‌شوند

بیشتر توسعه‌دهندگان این الزام را از طریق یک سند تدارکات (procurement) می‌بینند. مناقصه‌های بخش دولتی در چندین حوزه قضایی، شکل استانداردشده ISO از Open XML را می‌خواهند، نه شکل انتقالی‌ای که آفیس به‌طور پیش‌فرض می‌نویسد، و یک بایگانی که ISO 29500 Strict را الزامی می‌کند، یک .xlsx عادی را رد می‌کند حتی اگر اکسل آن را کاملاً باز کند. فضاهای نام انتقالی برای پشتیبانی از رفتار باینری قدیمی وجود دارند؛ فضاهای سخت‌گیرانه خود استاندارد اصلی هستند

واقعاً چه تفاوتی بین Strict و Transitional وجود دارد؟

تفاوت قابل‌مشاهده، واژگان است. بخش کارپوشه سخت‌گیرانه http://purl.oclc.org/ooxml/spreadsheetml/main را به‌عنوان فضای نام ریشه خود و http://purl.oclc.org/ooxml/officeDocument/relationships را برای ارجاعات رابطه اعلام می‌کند، و هیچ فضای نام انتقالی نباید در هیچ‌جای بسته باقی بماند. انواع رابطه هم به‌همراه آن تغییر می‌کنند، بنابراین بخش رابطه‌های ریشه، .../ooxml/officeDocument/relationships/officeDocument را به‌جای معادل آشنای openxmlformats نام می‌برد، و نوع ویژگی‌های گسترده‌یافته به‌صورت camelCase یعنی extendedProperties نوشته می‌شود

تفاوت نامرئی، دامنه است. Strict به‌عمد بخش‌هایی از شمای انتقالی را که فقط برای رفت‌وبرگشت فایل‌های باینری قدیمی وجود داشتند، به‌همراه گسترش‌های فروشنده‌ای که آفیس بعداً افزود، حذف می‌کند. به همین دلیل تبدیل، یک جست‌وجو-و-جایگزینی روی رشته‌ها نیست: برخی ویژگی‌ها به‌سادگی هیچ املای سخت‌گیرانه‌ای ندارند و اصلاً نباید نوشته شوند

روشن‌کردن آن

کد نویسندگی معمولی تغییر نمی‌کند. کارپوشه را همان‌طور که همیشه انجام می‌دهید بسازید، پرچم را تنظیم کنید و ذخیره کنید:

var
  Wb: TXLSXWorkbook;
  Sh: TXLSXWorksheet;
begin
  Wb := TXLSXWorkbook.Create;
  try
    Sh := Wb.Sheets.Add('Data');
    Sh.Cells[1, 1].Value := 'Product';
    Sh.Cells[1, 2].Value := 'Amount';
    Sh.Cells[2, 1].Value := 'Widget';
    Sh.Cells[2, 2].Value := 17;
    Sh.Cells[3, 2].Formula := '=SUM(B2:B2)';

    Wb.StrictOOXML := True;          // خروجی ISO/IEC 29500 Strict
    if Wb.SaveAs('archive-copy.xlsx') <> 1 then
      raise Exception.Create('strict save failed');
  finally
    Wb.Free;
  end;
end;

پرچم در ابتدای هر عملیات ذخیره‌سازی بازنشانی می‌شود و از ویژگی کارپوشه دوباره تخصیص می‌یابد، بنابراین یک استثنا در حین یک ذخیره‌سازی نمی‌تواند حالت سخت‌گیرانه را به ذخیره‌سازی بعدی نشت دهد. این جزئیات در فرایندهای سرور که در آن‌ها یک شیء کارپوشه واحد به چندین درخواست صادرات خدمت می‌کند، اهمیت دارد

چرا یک ذخیره‌سازی سخت‌گیرانه می‌تواند از اجرا سر باز زند؟

چهار خانواده ویژگی، گسترش‌های مایکروسافت هستند که هیچ معادل ISO 29500 Strict ندارند، و HotXLS در زمان ذخیره‌سازی یک استثنا صادر می‌کند به‌جای انتشار بسته‌ای که ادعای انطباق سخت‌گیرانه می‌کند اما نیست:

// خروجی Strict نمی‌تواند یک پروژه VBA را تعبیه کند
//   -> کارپوشه‌های دارای ماکرو را به‌صورت .xlsm انتقالی ذخیره کنید
// خروجی Strict نمی‌تواند کنترل‌های فرم را حمل کند
//   -> دکمه‌ها، چک‌باکس‌ها، جعبه‌های ترکیبی و ctrlProps آن‌ها
// خروجی Strict نمی‌تواند نظرات رشته‌ای (threaded) را حمل کند
//   -> مدل مدرن اشخاص/رشته‌ها، نه یادداشت‌های کلاسیک
// خروجی Strict نمی‌تواند فراداده آرایه پویا را حمل کند
//   -> بازه‌های ریزش (spill) که از طریق بخش فراداده ثبت شده‌اند

شکست با صدای بلند، معاوضه درست در اینجاست. یک پروژه VBA که به‌طور خاموش دور ریخته شود، یک کارپوشه کارآمد را به کارپوشه‌ای خراب تبدیل می‌کند که همچنان باز می‌شود، و گزارش این شکست هفته‌ها بعد از یک کاربر می‌رسد. یک استثنا ویژگی و پراپرتی‌ای را که باید تغییر کند نام می‌برد، درحالی‌که کد فراخوانی‌کننده هنوز می‌داند چه چیزی را صادر می‌کرده است. حفظ ماکرو و پیوند خارجی در مسیر انتقالی در حفظ پروژه‌های VBA و پیوندهای خارجی پوشش داده شده

دو خانواده گسترش‌یافته به‌شکل متفاوتی مدیریت می‌شوند، و دانستن دلیل آن ارزش دارد. نوارهای داده (data bars)، اسپارک‌لاین‌ها و ویژگی‌های مشابه در واژگان x14 و xm قرار دارند، و نسخه‌های SVG تصاویر در c15 قرار دارند. این‌ها محتوای فهرست گسترش‌یافته هستند که فضای نام‌شان خودتوصیف است، تجزیه‌کننده‌های عمومی صفحه‌گسترده آن‌ها را تحمل می‌کنند، و هیچ معادل ISO برای ترجمه‌شدن به آن وجود ندارد. HotXLS آن‌ها را نگه می‌دارد به‌جای آنکه محتوای کاربر را کنار بیندازد. اگر اعتبارسنج در خط‌لوله شما نسبت به گسترش‌ها هم مانند فضاهای نام سخت‌گیر است، آن ویژگی‌ها را پیش از صادرات از کارپوشه منبع حذف کنید

ترجمه باید به بخش‌هایی برسد که معمولاً هیچ‌کس آن‌ها را بازنویسی نمی‌کند

مسئله جالب مهندسی در خروجی سخت‌گیرانه، XML کاربرگ نیست. بخش‌هایی است که یک نویسنده سریع ترجیح می‌دهد آن‌ها را عیناً کپی کند. HotXLS تم‌ها، اتصالات، پیوندهای خارجی، نمودارها و بلاب‌های جدول‌محوری را با کپی‌کردن مستقیم بایت‌های فشرده اصلی‌شان حفظ می‌کند، که دقیقاً کار درست برای وفاداری است و دقیقاً کار نادرست برای خروجی سخت‌گیرانه، زیرا بایت‌های کپی‌شده فضاهای نام انتقالی را حمل می‌کنند

تحت StrictOOXML، آن پنج مسیر حفظ‌شده به بازسازی یا به یک بازپخش ترجمه‌ای تغییر می‌کنند و مسیر سریع کپی-بایت را دور می‌زنند. همه XML از یک روال ترجمه واحد عبور می‌کند، که روی مقادیر ویژگی داخل گیومه دوگانه لنگر می‌اندازد تا رشته‌ای شبیه به URI درون یک سلول هرگز به‌طور تصادفی بازنویسی نشود. متن سلولی که همان URI را دارد به‌صورت یک نهاد (entity) در XML اسکیپ می‌شود، بنابراین جایگزینی لنگرشده نمی‌تواند آن را ببیند. نویسنده جریانی ابتدا اسکلت خود را ترجمه می‌کند و سپس در sheetData تقسیم می‌شود، زیرا بلوک‌های ردیف اصلاً هیچ URI واژگانی ندارند. مکانیزم‌های مرتبط برای مسیر حفظ، در رفت‌وبرگشت بدون افت تم‌ها، فهرست‌های گسترش‌یافته و calcChain پوشش داده شده

خواندن فایل‌هایی که اکسل به‌صورت سخت‌گیرانه ذخیره کرده

خروجی فقط نیمی از ماجراست. اکسل «Strict Open XML Spreadsheet» را به‌عنوان یک گزینه ذخیره‌سازی ارائه می‌دهد، و فایل‌های تولیدشده به آن شکل باید درست باز شوند. HotXLS انواع رابطه را در هر محل تجزیه رابطه در بسته، ریشه، پیوندهای خارجی، کاربرگ‌ها، طرح‌ها و جدول‌های محوری، نرمال‌سازی می‌کند، بنابراین یک نوع رابطه سخت‌گیرانه با همان ثابت داخلی معادل انتقالی‌اش مطابقت پیدا می‌کند

همتای سمت‌خواننده، نرمال‌سازی پیشوند فضای نام است، که به پیشوندهای دلخواه و هر دو واژگان اجازه می‌دهد به یک جدول نام یگانه تفکیک شوند. این کار به همان اندازه که به فایل‌های سخت‌گیرانه سود می‌رساند، به فایل‌های معمولی هم سود می‌رساند، زیرا تولیدکننده‌های شخص‌ثالث پیشوندها را آزادانه پیوند می‌دهند، و همان ماشین‌آلاتی است که در تفکیک رابطه OPC در بسته‌های XLSX شرح داده شده

یک فهرست کوتاه پیش از عرضه خروجی سخت‌گیرانه

با بسته تأیید کنید، نه با اکسل. اکسل هر دو شکل را با خوشحالی باز می‌کند، بنابراین یک بازکردن موفق چیزی درباره انطباق ثابت نمی‌کند. نتیجه را از حالت فشرده خارج کنید و تأیید کنید که xl/workbook.xml فضای نام purl را اعلام می‌کند، هیچ بخشی حاوی schemas.openxmlformats.org/spreadsheetml نیست، و انواع رابطه در _rels/.rels و xl/_rels/workbook.xml.rels از شکل‌های سخت‌گیرانه استفاده می‌کنند

سپس فایل را دوباره از طریق HotXLS باز کنید و مقادیر، فرمول‌ها، قالب‌ها و ابرپیوندها را در برابر منبع مقایسه کنید. یک آزمون بازخوانی تنها راه ارزان برای اثبات این است که ترجمه به محتوا آسیب نزده، و همزمان نرمال‌سازی سمت‌خواننده را نیز آزمایش می‌کند. اگر کارپوشه‌های شما نمودار دارند، آن‌ها را هم بررسی کنید، زیرا بخش نمودار یکی از بخش‌های حفظ‌شده است که تحت حالت سخت‌گیرانه به یک مسیر بازسازی‌شده تغییر می‌کند

خروجی سخت‌گیرانه، خواندن مدارا‌گر و حفظ بدون افت، همگی بخشی از یک موتور OOXML واحد برای دلفی و C++Builder هستند؛ فهرست کامل ویژگی‌ها در صفحه مؤلفه صفحه‌گسترده HotXLS برای دلفی قرار دارد