HotXLS כותבת חוברות עבודה ISO/IEC 29500 Strict Open XML מדלפי ומ-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 זורקת חריגה בזמן השמירה במקום לפלוט חבילה שטוענת לתאימות מחמירה ואינה כזו:
// פלט Strict לא יכול להטמיע פרויקט VBA
// -> שמרו חוברות עבודה עם מאקרו כ-.xlsm מעברי
// פלט Strict לא יכול לשאת פקדי טופס
// -> כפתורים, תיבות סימון, תיבות משולבות ו-ctrlProps שלהם
// פלט Strict לא יכול לשאת הערות משורשרות
// -> מודל persons/threads המודרני, לא הערות קלאסיות
// פלט Strict לא יכול לשאת מטא-נתוני מערך דינמי
// -> טווחי גלישה הרשומים דרך חלק המטא-נתונים
כישלון בקול רם הוא הפשרה הנכונה כאן. פרויקט VBA שנשמט בשקט הופך חוברת עבודה תקינה לשבורה שעדיין נפתחת, ודיווח הכשל מגיע ממשתמש כעבור שבועות. חריגה נוקבת את התכונה ואת המאפיין לשינוי בעוד הקוד הקורא עדיין יודע מה הוא ייצא. שימור מאקרו וקישורים חיצוניים בנתיב המעברי מכוסה בשימור פרויקטי VBA וקישורים חיצוניים
שתי משפחות הרחבה מטופלות אחרת, וכדאי לדעת למה. פסי נתונים, גרפי מיני-מגמה ותכונות דומות חיות באוצרות המילים x14 ו-xm, ווריאנטי ה-SVG של תמונות חיים ב-c15. אלה תוכן רשימת הרחבה שמרחבי השם שלהם מתארים את עצמם, מפרשי גיליון אלקטרוני כלליים סובלניים כלפיהם, ואין להם מקבילה ב-ISO לתרגום. HotXLS שומרת אותם במקום להשליך תוכן משתמש לאדמה. אם מאמת בצינור העבודה שלכם מחמיר גם כלפי הרחבות ולא רק כלפי מרחבי שמות, הסירו תכונות אלה מחוברת העבודה המקורית לפני הייצוא
התרגום חייב להגיע לחלקים שאף אחד בדרך כלל לא כותב מחדש
בעיית ההנדסה המעניינת בפלט מחמיר אינה ה-XML של גיליון העבודה. אלה החלקים שכותב מהיר היה מעדיף להעתיק כלשונם. HotXLS שומרת ערכות נושא, חיבורים, קישורים חיצוניים, תרשימים וגושי ציר בהעתקת הבייטים הדחוסים המקוריים שלהם ישירות דרך, מה שנכון בדיוק לנאמנות ושגוי בדיוק עבור פלט מחמיר, מכיוון שבייטים שהועתקו נושאים מרחבי שמות מעבריים
תחת StrictOOXML, חמשת הנתיבים המשומרים הללו עוברים לבנייה מחדש או לשחזור מתרגם, תוך עקיפת נתיב ההעתקה המהירה. כל ה-XML עובר דרך שגרת תרגום אחת, שמעגנת על ערכי תכונות מוקפים במרכאות כפולות כך שמחרוזת שנראית כמו URI בתוך תא לעולם לא יכולה להיכתב מחדש בטעות. טקסט תא המכיל אותו URI נמלט כישות ב-XML, כך שההחלפה המעוגנת לא יכולה לראות אותו. הכותב הזורם מתרגם את השלד שלו קודם ואז מפצל ב-sheetData, מכיוון שבלוקי השורות לא מכילים כלל URI של אוצר מילים. מנגנונים קשורים לנתיב השימור מכוסים בהלוך-חזור חסר אובדן של ערכות נושא, רשימות הרחבה ו-calcChain
קריאת קבצים ש-Excel שמר כמחמירים
הפלט הוא רק חצי מהסיפור. Excel מציע "Strict Open XML Spreadsheet" כאפשרות שמירה, וקבצים שנוצרו בדרך זו חייבים להיפתח נכון. HotXLS מנרמלת סוגי קשרים בכל אתר ניתוח קשרים בחבילה, השורש, קישורים חיצוניים, גיליונות עבודה, שרטוטים וטבלאות ציר, כך שסוג קשר מחמיר תואם לאותו קבוע פנימי כמו המקבילה המעברית שלו
המקבילה בצד הקורא היא נרמול קידומות מרחב שם, המאפשר לקידומות שרירותיות ולשני אוצרות המילים להיפתר לטבלת שם קנונית אחת. עבודה זו מועילה גם לקבצים רגילים וגם למחמירים, מכיוון שמחוללי צד-שלישי קושרים קידומות באופן חופשי, וזהו אותו מנגנון המתואר בפענוח קשרי OPC בחבילות XLSX
רשימת בדיקה קצרה לפני משלוח פלט מחמיר
אמתו עם החבילה, לא עם Excel. Excel פותח את שתי הצורות בשמחה, כך שפתיחה מוצלחת לא מוכיחה דבר לגבי תאימות. חלצו את התוצאה מהמכל ואמתו של-xl/workbook.xml יש הכרזת מרחב השם של purl, שאף חלק לא מכיל schemas.openxmlformats.org/spreadsheetml, ושסוגי קשרים ב-_rels/.rels וב-xl/_rels/workbook.xml.rels משתמשים בצורות המחמירות
לאחר מכן פתחו את הקובץ מחדש דרך HotXLS והשוו ערכים, נוסחאות, פורמטים וקישורים כנגד המקור. בדיקת קריאה-חזרה היא הדרך הזולה היחידה להוכיח שהתרגום לא פגע בתוכן, והיא מפעילה בו-זמנית גם את הנרמול בצד הקורא. אם חוברות העבודה שלכם נושאות תרשימים, בדקו גם אותם, מכיוון שחלק התרשים הוא אחד החלקים המשומרים שעובר לנתיב בנוי-מחדש תחת מצב מחמיר
פלט מחמיר, קריאה סובלנית ושימור חסר אובדן הם כולם חלק מאותו מנוע OOXML לדלפי ו-C++Builder; רשימת התכונות המלאה נמצאת בעמוד רכיב הגיליון האלקטרוני HotXLS Delphi