martes, 31 de mayo de 2011

Editar archivos xlsx desde OOXML

En alguna ocasión en uno de mis trabajos de programador me toco convivir con los archivos de Excel 2007, ya requería de editar un archivo. Voy a explicar como funcionan de manera general como editarlos y dependiendo de las necesidades se pueden crear rutinas para editarlos.
Este formato está basado en el estándar de OOXML de Microsoft así que si tienen un libro sobre eso ahí se detalla a mayor profundidad todo.
Los archivos .xlsx son archivos comprimidos, es decir, si ahorita tomas un archivo con esta extensión y la cambias a .zip, al descomprimirla obtendrás varios archivos con extensión .xml en el cual están contenidos formatos de celdas, información, imágenes y la agrupación las hojas, toda la información esta estructurada.
En este archivo binario encontrarás contenidos archivos xml en la ruta \xl\worksheets\sheet1.xml, \xl\worksheets\sheet2.xml, hasta n ojas dependiendo del numero de hojas que tu documento de Excel tenga y el contenido es similar a:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
                <dimension ref="C4:C9"/>
                <sheetViews>
                                <sheetView tabSelected="1" workbookViewId="0">
                                                <selection activeCell="C10" sqref="C10"/>
                                </sheetView>
                </sheetViews>
                <sheetFormatPr defaultRowHeight="15"/>
                <sheetData>
                                <row r="4" spans="3:3">
                                                <c r="C4" t="s">
                                                                <v>0</v>
                                                </c>
                                </row>
                                <row r="5" spans="3:3">
                                                <c r="C5" t="s">
                                                                <v>1</v>
                                                </c>
                                </row>
                                <row r="6" spans="3:3">
                                                <c r="C6" t="s">
                                                                <v>2</v>
                                                </c>
                                </row>
                                <row r="7" spans="3:3">
                                                <c r="C7" t="s">
                                                                <v>3</v>
                                                </c>
                                </row>
                                <row r="8" spans="3:3">
                                                <c r="C8" t="s">
                                                                <v>4</v>
                                                </c>
                                </row>
                                <row r="9" spans="3:3">
                                                <c r="C9" t="s">
                                                                <v>5</v>
                                                </c>
                                </row>
                </sheetData>
                <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
</worksheet>


Dentro de el tag <v>Num</v> se encuentra una referencia numérica que puedes locacilzar en el archivo \xl\sharedStrings.xml donde aparece los siguiente:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="6" uniqueCount="6">
                <si>
                                <t>est</t>
                </si>
                <si>
                                <t xml:space="preserve">es </t>
                </si>
                <si>
                                <t>una</t></si>
                <si>
                                <t>prueba</t>
                </si>
                <si>
                                <t>desde</t>
                </si>
                <si>
                                <t>el excel</t>
                </si>
</sst>

En donde este archivo esta estructurado a manera de arreglo es decir la posición 0 marcada en archivo \xl\worksheets\sheet1.xml:

<c r="C4" t="s">
                                                                <v>0</v>
                                                </c>
Hace referencia a el valor en \xl\sharedStrings.xml:

<si>
                                <t>est</t>
                </si>

A continuación describo el algoritmo y ustedes lo plasman en cualquier legunaje:

1.       Lo que se requiere es una librería de cualquier lenguaje que pueda leer archivos zip para descompirmirlo en algún directorio temporal
2.       Una vez descomprimido requerimos de manipular los xml, ya sea para agregar o quitar ramas de la estructura.
3.       Una vez terminada la operación con los archivos xml requerimos generar el archivo zip de nuevo, pero conextensión xlsx.

No profundicé mucho en el tema debido a que estas son las bases, cabe señalar que este tipo de arquitectura aplica paro el Office 2010. Si tienen alguna duda con gusto les puedo apoyar.