HotXLS записує книги Open XML у форматі ISO/IEC 29500 Strict з Delphi та C++Builder, встановивши єдину властивість, StrictOOXML, перед збереженням. Кожна частина пакета, від xl/workbook.xml до файлів зв'язків і типів вмісту, записується за строгими словниками purl.oclc.org замість перехідних schemas.openxmlformats.org, а можливості, які Strict не дозволяє, відхиляються явним винятком, а не все одно записуються
Більшість розробників стикаються з цією вимогою через закупівельний документ. Тендери державного сектору в кількох юрисдикціях вимагають стандартизовану ISO форму Open XML, а не перехідну форму, яку Office записує за замовчуванням, і архів, що вимагає ISO 29500 Strict, відхилить звичайний .xlsx, навіть якщо Excel відкриває його бездоганно. Перехідні простори імен існують, щоб враховувати застарілу двійкову поведінку; строгі — це власне стандарт
Що насправді відрізняється між Strict і Transitional?
Видима різниця — словник. Частина строгої книги декларує http://purl.oclc.org/ooxml/spreadsheetml/main як кореневий простір імен і http://purl.oclc.org/ooxml/officeDocument/relationships для посилань на зв'язки, і жоден перехідний простір імен не може вижити ніде в пакеті. Разом з тим змінюються й типи зв'язків, тож коренева частина зв'язків називає .../ooxml/officeDocument/relationships/officeDocument замість звичного еквівалента openxmlformats, а тип розширених властивостей записується у стилі camelCase як extendedProperties
Невидима різниця — обсяг. Strict свідомо опускає частини перехідної схеми, що існували лише для двостороннього перетворення застарілих двійкових файлів, а також розширення постачальника, які Office додав пізніше. Ось чому конвертація — це не пошук і заміна рядків: деякі можливості просто не мають строгого запису й не повинні записуватися взагалі
Вмикання
Звичайний код створення не змінюється. Побудуйте книгу так, як завжди, встановіть прапорець і збережіть:
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;
Прапорець скидається на початку кожної операції збереження й повторно призначається з властивості книги, тож виняток під час одного збереження не може просочити строгий режим у наступне. Ця деталь важлива в серверних процесах, де один об'єкт книги обслуговує кілька запитів на експорт
Чому строге збереження може відмовитися виконуватись?
Чотири родини можливостей — це розширення Microsoft без еквівалента в ISO 29500 Strict, і HotXLS порушує виняток під час збереження, а не видає пакет, що заявляє про строгу відповідність, хоча насправді її не має:
// Строгий вивід не може вбудувати проєкт VBA
// -> зберігайте книги з макросами як перехідні .xlsm
// Строгий вивід не може нести елементи керування форми
// -> кнопки, прапорці, розкривні списки та їхні ctrlProps
// Строгий вивід не може нести потокові коментарі
// -> сучасна модель persons/threads, не класичні примітки
// Строгий вивід не може нести метадані динамічних масивів
// -> діапазони розливу, записані через частину метаданих
Гучний збій — правильний компроміс тут. Мовчки відкинутий проєкт VBA перетворює робочу книгу на зламану, яка все ще відкривається, а повідомлення про збій приходить від користувача через кілька тижнів. Виняток називає можливість і властивість, яку слід змінити, поки код, що викликає, ще знає, що саме він експортував. Збереження макросів і зовнішніх зв'язків на перехідному шляху описано у статті збереження проєктів VBA та зовнішніх зв'язків
Дві родини розширень обробляються інакше, і варто знати чому. Гістограми даних, спарклайни та подібні можливості живуть у словниках x14 та xm, а SVG-варіанти зображень живуть у c15. Це вміст списку розширень, чиї простори імен самоописові, звичайні парсери електронних таблиць їх толерують, і немає ISO-еквівалента, у який їх перекласти. HotXLS зберігає їх, а не викидає користувацький вміст. Якщо валідатор у вашому конвеєрі строгий і щодо розширень, і щодо просторів імен, видаліть ці можливості з вихідної книги перед експортом
Переклад має досягати частин, які зазвичай ніхто не переписує
Цікава інженерна задача строгого виводу — не XML аркуша. Це частини, які швидкий записувач радше скопіював би дослівно. HotXLS зберігає теми, з'єднання, зовнішні зв'язки, діаграми та зведені блоки, копіюючи їхні оригінальні стиснуті байти безпосередньо, що є цілком правильним для точності відтворення й цілком неправильним для строгого виводу, бо скопійовані байти несуть перехідні простори імен
Під дією StrictOOXML ці п'ять збережених шляхів переходять на перебудову або перекладне відтворення, оминаючи швидкий шлях копіювання байтів. Увесь XML проходить через одну процедуру перекладу, що прив'язується до значень атрибутів у подвійних лапках, тож рядок, схожий на URI, всередині клітинки ніколи не буде переписаний випадково. Текст клітинки, що містить той самий URI, екранується як сутність у XML, тож прив'язана заміна його не бачить. Потоковий записувач спочатку перекладає свій скелет, а потім розділяється на sheetData, оскільки блоки рядків взагалі не містять URI словника. Пов'язана механіка шляху збереження описана у статті безвтратні двосторонні перетворення тем, списків розширень і calcChain
Читання файлів, які Excel зберіг як строгі
Вивід — це лише половина історії. Excel пропонує «Строга електронна таблиця Open XML» як варіант збереження, і файли, створені в такий спосіб, мають відкриватися коректно. HotXLS нормалізує типи зв'язків у кожному місці розбору зв'язків у пакеті — корені, зовнішні зв'язки, аркуші, малюнки та зведені таблиці, тож строгий тип зв'язку зіставляється з тією самою внутрішньою константою, що й його перехідний відповідник
Відповідник з боку читання — нормалізація префіксів простору імен, яка дозволяє довільним префіксам і обом словникам зводитися до однієї канонічної таблиці імен. Ця робота приносить користь і звичайним файлам, і строгим, оскільки сторонні генератори прив'язують префікси вільно, і це та сама механіка, описана у статті розв'язання зв'язків OPC у пакетах XLSX
Короткий контрольний список перед випуском строгого виводу
Перевіряйте пакетом, а не Excel. Excel охоче відкриває обидві форми, тож успішне відкриття нічого не доводить про відповідність. Розпакуйте результат і переконайтеся, що xl/workbook.xml декларує простір імен purl, що жодна частина не містить schemas.openxmlformats.org/spreadsheetml, і що типи зв'язків у _rels/.rels та xl/_rels/workbook.xml.rels використовують строгі форми
Потім повторно відкрийте файл через HotXLS і порівняйте значення, формули, формати та гіперпосилання з джерелом. Тест зі зворотним читанням — єдиний дешевий спосіб довести, що переклад не пошкодив вміст, і водночас він задіює нормалізацію з боку читання. Якщо ваші книги несуть діаграми, перевірте й їх, оскільки частина діаграми — одна з тих збережених частин, що переходить на перебудований шлях у строгому режимі
Строгий вивід, толерантне читання та безвтратне збереження — усе це частини того самого рушія OOXML для Delphi та C++Builder; повний перелік можливостей на сторінці компонента електронних таблиць HotXLS для Delphi