HotXLS escribe libros Open XML ISO/IEC 29500 Strict desde Delphi y C++Builder estableciendo una única 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 strict de purl.oclc.org en lugar de los transicionales de 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 pliego de contratación pública. Las licitaciones del sector público de varias jurisdicciones exigen la forma estandarizada ISO de Open XML, no la forma transicional que Office escribe por defecto, 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 strict son el estándar propiamente dicho
¿Qué diferencia realmente a Strict de Transitional?
La diferencia visible es el vocabulario. Una parte de libro strict 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 ningún lugar del paquete. Los tipos de relación cambian con ello, de modo que la parte de relaciones raíz se llama .../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 permitir el ida y vuelta con archivos binarios heredados, junto con las extensiones de proveedor que Office añadió después. Por eso la conversión no es una búsqueda y sustitución de cadenas: algunas funciones simplemente no tienen forma strict y no deben escribirse en absoluto
Activarlo
El código de creación habitual no cambia. Construya el libro de la forma en que siempre lo hace, active el indicador y guarde:
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 modo que una excepción durante un guardado no puede filtrar el modo strict al siguiente. Ese detalle importa en procesos de servidor donde un único objeto de libro 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 cumplir strict sin ser cierto:
// La salida Strict no puede incrustar un proyecto VBA
// -> guarde los libros 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 arrays dinámicos
// -> rangos de desbordamiento registrados a través de la parte de metadatos
Fallar de forma ruidosa es la decisión correcta aquí. Un proyecto VBA descartado silenciosamente convierte un libro funcional en uno roto que aún se abre, y el informe del fallo llega de un usuario semanas después. Una excepción nombra la función y la propiedad que hay que cambiar mientras el código que llama todavía sabe qué estaba exportando. La preservación de macros y enlaces externos en la vía transicional se trata en preservar proyectos VBA y enlaces externos
Dos familias de extensiones se tratan de forma distinta, y vale la pena saber por qué. Las barras de datos, los minigráficos y funciones similares residen en los vocabularios x14 y xm, y las variantes SVG de las imágenes residen en c15. Se trata de contenido de lista de extensión cuyos espacios de nombres son autodescriptivos, los analizadores de hojas de cálculo generales los toleran, y no existe un equivalente ISO al que traducirlos. HotXLS los conserva en lugar de descartar contenido del usuario. Si un validador de su canalización es estricto también con las extensiones además de con los espacios de nombres, elimine esas funciones del libro 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. Son las partes que un escritor rápido preferiría copiar literalmente. HotXLS preserva los temas, las conexiones, los enlaces externos, los gráficos y los blobs de tablas dinámicas copiando directamente sus bytes comprimidos originales, que es exactamente lo correcto para la fidelidad y exactamente lo incorrecto para la salida strict, porque los bytes copiados llevan espacios de nombres transicionales
Con StrictOOXML, esas cinco vías preservadas pasan a reconstrucción o a una repetición con traducción, evitando la vía rápida de copia de bytes. Todo el XML pasa por una única rutina de traducción, que se ancla en los valores de atributo entre comillas dobles para que una cadena con apariencia 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, de modo que el reemplazo anclado no puede verlo. El escritor en flujo traduce primero su esqueleto y luego se divide en sheetData, ya que los bloques de filas no contienen ningún URI de vocabulario en absoluto. La mecánica relacionada de la vía de preservación se trata en los ida y vuelta sin pérdida de temas, listas de extensión y calcChain
Leer archivos que Excel guardó como strict
La escritura 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 así deben abrirse correctamente. HotXLS normaliza los tipos de relación en cada punto de análisis de relaciones del paquete, la raíz, los enlaces externos, las hojas de cálculo, los dibujos y las tablas dinámicas, de modo que un tipo de relación strict coincide con la misma constante interna que su equivalente transicional
La contrapartida en el lado de la lectura es la normalización de prefijos de espacio de nombres, que permite que prefijos arbitrarios y ambos vocabularios se resuelvan en una única tabla de nombres canónica. Ese trabajo beneficia tanto a los archivos ordinarios como a los strict, ya que los generadores de terceros vinculan prefijos libremente, y es la misma maquinaria descrita en la resolución de relaciones OPC en paquetes XLSX
Una breve lista de comprobación antes de publicar salida strict
Verifique con el paquete, no con Excel. Excel abre ambas formas sin problema, así que una apertura exitosa no demuestra nada sobre la conformidad. Descomprima el resultado y confirme 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
A continuación, vuelva a abrir el archivo con HotXLS y compare valores, fórmulas, formatos e hipervínculos con el origen. Una prueba de relectura es la única forma económica de demostrar que la traducción no dañó el contenido, y al mismo tiempo pone a prueba la normalización del lado de la lectura. Si sus libros llevan gráficos, compruébelos también, ya que la parte de gráfico es una de las partes preservadas que pasa a una vía 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 hojas de cálculo para Delphi de HotXLS