HotXLS escribe libros de trabajo Open XML ISO/IEC 29500 Strict desde Delphi y C++Builder configurando una sola propiedad, StrictOOXML, antes de guardar. Cada parte del paquete, desde xl/workbook.xml hasta los archivos de relaciones y los tipos de contenido, se escribe con los vocabularios estrictos purl.oclc.org en lugar de los transicionales schemas.openxmlformats.org, y las funciones que Strict no permite se rechazan con una excepción explícita en lugar de escribirse de todos modos
La mayoría de los desarrolladores se encuentran con este requisito a través de un documento de contratación. Las licitaciones del sector público en varias jurisdicciones piden la forma estandarizada por ISO de Open XML, no la forma transicional que Office escribe de manera predeterminada, y un archivo que exige ISO 29500 Strict rechazará un .xlsx normal aunque Excel lo abra perfectamente. Los espacios de nombres transicionales existen para dar cabida al comportamiento binario heredado; los estrictos son el estándar propiamente dicho
¿Qué difiere realmente entre Strict y Transitional?
La diferencia visible es el vocabulario. Una parte de libro de trabajo estricto declara http://purl.oclc.org/ooxml/spreadsheetml/main como su espacio de nombres raíz y http://purl.oclc.org/ooxml/officeDocument/relationships para las referencias de relación, y ningún espacio de nombres transicional puede sobrevivir en ninguna parte del paquete. Los tipos de relación cambian junto con esto, así que la parte de relaciones raíz nombra .../ooxml/officeDocument/relationships/officeDocument en lugar del equivalente familiar de openxmlformats, y el tipo de propiedades extendidas se escribe en camelCase como extendedProperties
La diferencia invisible es el alcance. Strict omite deliberadamente partes del esquema transicional que solo existían para conservar la compatibilidad con archivos binarios heredados, junto con las extensiones de proveedor que Office agregó después. Por eso la conversión no es una simple búsqueda y reemplazo de cadenas: algunas funciones sencillamente no tienen una forma estricta y no deben escribirse en absoluto
Activarlo
El código de autoría ordinario no cambia. Construye el libro de trabajo como siempre, activa el indicador y guarda:
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; // salida ISO/IEC 29500 Strict
if Wb.SaveAs('archive-copy.xlsx') <> 1 then
raise Exception.Create('strict save failed');
finally
Wb.Free;
end;
end;
El indicador se restablece al inicio de cada operación de guardado y se reasigna a partir de la propiedad del libro de trabajo, así que una excepción durante un guardado no puede filtrar el modo strict hacia el siguiente. Ese detalle importa en procesos de servidor donde un solo objeto de libro de trabajo atiende varias solicitudes de exportación
¿Por qué puede un guardado strict negarse a ejecutarse?
Cuatro familias de funciones son extensiones de Microsoft sin equivalente en ISO 29500 Strict, y HotXLS genera una excepción en el momento de guardar en lugar de emitir un paquete que afirma conformidad estricta sin serlo:
// La salida Strict no puede incrustar un proyecto VBA
// -> guarda los libros de trabajo con macros como .xlsm transicional
// La salida Strict no puede llevar controles de formulario
// -> botones, casillas de verificación, cuadros combinados y sus ctrlProps
// La salida Strict no puede llevar comentarios en hilo
// -> el modelo moderno de personas/hilos, no las notas clásicas
// La salida Strict no puede llevar metadatos de arreglos dinámicos
// -> rangos de desbordamiento registrados a través de la parte de metadatos
Fallar ruidosamente es la decisión correcta aquí. Un proyecto VBA descartado en silencio convierte un libro de trabajo funcional en uno roto que igual se abre, y el reporte de la falla llega de un usuario semanas después. Una excepción nombra la función y la propiedad a cambiar mientras el código que llama todavía sabe qué estaba exportando. La preservación de macros y vínculos externos en la ruta transicional se cubre en preservación de proyectos VBA y vínculos externos
Dos familias de extensiones se manejan de forma distinta, y vale la pena saber por qué. Las barras de datos, las minigráficas y funciones similares residen en los vocabularios x14 y xm, y las variantes SVG de las imágenes residen en c15. Este es contenido de lista de extensión cuyos espacios de nombres se describen a sí mismos, los analizadores de hojas de cálculo genéricos los toleran, y no existe un equivalente ISO al cual traducirlos. HotXLS los conserva en lugar de descartar contenido del usuario. Si un validador en tu canalización es estricto también respecto a las extensiones, no solo a los espacios de nombres, elimina esas funciones del libro de trabajo de origen antes de exportar
La traducción tiene que alcanzar partes que normalmente nadie reescribe
El problema de ingeniería interesante en la salida strict no es el XML de la hoja de cálculo. Es las partes que un escritor rápido preferiría copiar tal cual. HotXLS preserva temas, conexiones, vínculos externos, gráficos y blobs de tablas dinámicas copiando directamente sus bytes comprimidos originales, lo cual es exactamente lo correcto para la fidelidad y exactamente lo incorrecto para la salida strict, porque los bytes copiados llevan espacios de nombres transicionales
Bajo StrictOOXML, esas cinco rutas preservadas cambian a una reconstrucción o a una repetición con traducción, evitando la ruta rápida de copia de bytes. Todo el XML pasa por una sola rutina de traducción, que se ancla en los valores de atributo entre comillas dobles para que una cadena con aspecto de URI dentro de una celda nunca pueda reescribirse por accidente. El texto de celda que contiene esa misma URI se escapa como entidad en el XML, así que el reemplazo anclado no puede verlo. El escritor en flujo traduce primero su esqueleto y luego divide en sheetData, ya que los bloques de fila no contienen ninguna URI de vocabulario en absoluto. La mecánica relacionada de la ruta de preservación se cubre en preservación sin pérdida de temas, listas de extensión y calcChain
Leer archivos que Excel guardó como strict
La salida es solo la mitad de la historia. Excel ofrece "Hoja de cálculo Open XML estricta" como opción de guardado, y los archivos producidos de esa manera deben abrirse correctamente. HotXLS normaliza los tipos de relación en cada punto de análisis de relaciones del paquete, la raíz, los vínculos externos, las hojas de cálculo, los dibujos y las tablas dinámicas, de modo que un tipo de relación strict coincida con la misma constante interna que su contraparte transicional
La contraparte del lado del lector es la normalización de prefijos de espacio de nombres, que permite prefijos arbitrarios y hace que ambos vocabularios se resuelvan hacia una sola tabla de nombres canónica. Ese trabajo beneficia tanto a los archivos ordinarios como a los strict, ya que los generadores de terceros asignan prefijos libremente, y es la misma maquinaria descrita en resolución de relaciones OPC en paquetes XLSX
Una lista breve antes de publicar salida strict
Verifica con el paquete, no con Excel. Excel abre ambas formas sin problema, así que una apertura exitosa no demuestra nada sobre la conformidad. Descomprime el resultado y confirma que xl/workbook.xml declara el espacio de nombres purl, que ninguna parte contiene schemas.openxmlformats.org/spreadsheetml, y que los tipos de relación en _rels/.rels y xl/_rels/workbook.xml.rels usan las formas strict
Luego vuelve a abrir el archivo con HotXLS y compara valores, fórmulas, formatos e hipervínculos contra el origen. Una prueba de relectura es la única forma económica de comprobar que la traducción no dañó el contenido, y a la vez ejercita la normalización del lado del lector. Si tus libros de trabajo llevan gráficos, verifica también esos, ya que la parte de gráfico es una de las partes preservadas que cambia a una ruta reconstruida en modo strict
La salida strict, la lectura tolerante y la preservación sin pérdida forman parte del mismo motor OOXML para Delphi y C++Builder; la lista completa de funciones está en la página del componente de hoja de cálculo para Delphi HotXLS