Excel and ZIP
iXML provides dedicated namespaces for working with Excel spreadsheets (excel) and ZIP archives (zip).
Excel Workbooks
excel:workbook
Creates a new workbook or opens an existing one. All Excel operations must be nested inside this element.
<!-- Create a new workbook -->
<excel:workbook>
<excel:set coords="A1" type="text">Name</excel:set>
<excel:set coords="B1" type="numeric">36</excel:set>
<excel:create var="book" format="xlsx"/>
</excel:workbook>
<!-- Open an existing file -->
<excel:workbook filename="./data/import.xlsx">
<excel:get var="val" coords="A1"/>
</excel:workbook>
Cell Operations
excel:set
Sets the value of a cell. Use type to control storage: text, numeric, date, bool, null, or auto (default).
<excel:set coords="A1" type="text">Product Name</excel:set>
<excel:set coords="B1" type="numeric" format="#,##0.00">49.99</excel:set>
<excel:set coords="C1" type="date">2024-01-15</excel:set>
Omitting type="numeric" for numbers may store them as strings, causing Excel formulas to fail.
excel:get
Gets the value of a cell. The type attribute controls the return: raw (default), calculated, or formatted.
<excel:get var="val" coords="A1"/>
Cursor Navigation
excel:setpos
Sets the cursor position by indices (0-based) or cell coordinates.
<excel:setpos sheet="0" row="5" col="0"/>
<excel:setpos coords="B3"/>
excel:getpos
Gets the current cursor position as coordinates and/or indices.
<excel:getpos var_coords="pos" var_sheet="s" var_row="r" var_col="c"/>
excel:next
Shifts the cursor by a given offset. Default advances one column.
<excel:next offset_row="1" offset_col="0"/>
excel:length
Gets the number of sheets, rows, and columns for the current cursor context.
<excel:length var_sheets="s" var_rows="r" var_cols="c"/>
Sheet Management
excel:addsheet
Adds a new sheet to the workbook.
<excel:addsheet>Summary</excel:addsheet>
<excel:setpos sheet="1"/>
<excel:set coords="A1">Summary Data</excel:set>
excel:removesheet
Removes a sheet by index (0-based).
Row and Column Management
excel:addrow / excel:removerow
Insert or remove rows. Accepts optional index and height attributes.
Full reference: addrow → | removerow →
excel:addcol / excel:removecol
Insert or remove columns. Accepts optional index and width attributes.
Full reference: addcol → | removecol →
Styling
excel:style
Applies styling to a cell range. The style is defined as a nested array with keys for font, alignment, borders, fill, and numberFormat.
<array var="headerStyle">
<array key="font">
<item key="bold">1</item>
<item key="size">12</item>
</array>
<array key="fill">
<item key="fillType">solid</item>
<array key="startColor"><item key="rgb">CCCCFF</item></array>
</array>
<array key="borders">
<array key="bottom">
<item key="borderStyle">thin</item>
</array>
</array>
</array>
<excel:style var="headerStyle">A1:B1</excel:style>
excel:autofilter
Enables auto-filter dropdown menus on a header range.
<excel:autofilter>A1:D100</excel:autofilter>
Data Export
excel:array
Extracts all cell values into a 3D array: data[sheet][row][col].
<excel:array var="data"/>
<output>$data[0][0][0]</output> <!-- First sheet, first row, first col -->
excel:create
Generates the workbook as binary data. Supported formats: csv, ods, xls, xlsx.
<excel:create var="book" format="xlsx"/>
<!-- Serve as download -->
<header>Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</header>
<header>Content-Disposition: attachment; filename="report.xlsx"</header>
<output>$book</output>
Practical Excel Patterns
Data Export with Styling
<excel:workbook title="Contact Export" subject="Monthly Report">
<!-- Header row -->
<excel:set coords="A1" type="text">Name</excel:set>
<excel:set coords="B1" type="text">Email</excel:set>
<excel:set coords="C1" type="text">Company</excel:set>
<excel:set coords="D1" type="text">Revenue</excel:set>
<!-- Style header -->
<array var="hdr">
<array key="font"><item key="bold">1</item><array key="color"><item key="rgb">FFFFFF</item></array></array>
<array key="fill">
<item key="fillType">solid</item>
<array key="startColor"><item key="rgb">4472C4</item></array>
</array>
</array>
<excel:style var="hdr">A1:D1</excel:style>
<!-- Data rows from database -->
<set var="row">2</set>
<db:select var="contacts" entity="contacts" limit="100" type="assoc">
<db:fields>c.name, c.email, c.company, c.volume</db:fields>
</db:select>
<foreach var="contacts" var_value="c">
<excel:set coords="A$row" type="text">$c.name</excel:set>
<excel:set coords="B$row" type="text">$c.email</excel:set>
<excel:set coords="C$row" type="text">$c.company</excel:set>
<excel:set coords="D$row" type="numeric" format="#,##0.00">$c.volume</excel:set>
<set var="row">$(($row + 1))</set>
</foreach>
<excel:autofilter>A1:D$row</excel:autofilter>
<excel:create var="book" format="xlsx"/>
</excel:workbook>
Reading an Uploaded Excel File
<excel:workbook filename="$uploaded_file" format="xlsx">
<excel:array var="data" type="raw"/>
<excel:length var_rows="total_rows"/>
</excel:workbook>
<!-- Process rows (skip header at index 0) -->
<set var="imported">0</set>
<for var="i" from="1" to="$total_rows">
<set var="name">$data[0][$i][0]</set>
<set var="email">$data[0][$i][1]</set>
<if value1="$name" func="!=">
<set var="imported">$(($imported + 1))</set>
</if>
</for>
<output>Imported $imported records</output>
ZIP Archives
The zip namespace provides commands for creating and reading ZIP archives. All operations (except zip:archive itself) must be nested inside a zip:archive element. Changes are committed when </zip:archive> is reached.
zip:archive
Creates a new archive or opens an existing one.
<zip:archive filename="./data/export.zip">
<zip:write filename="readme.txt">This is the readme.</zip:write>
<zip:write filename="data/report.csv">Name;Age&n;Ada;36</zip:write>
</zip:archive>
zip:write
Writes content to an entry in the archive, creating or overwriting it.
zip:read
Reads the content of an archive entry into a variable.
<zip:archive filename="./data/export.zip">
<zip:read var="readme" filename="readme.txt"/>
</zip:archive>
<output>$readme</output>
zip:exists
Checks whether an entry exists within the archive.
zip:status
Returns status information (name, size, compressed size, CRC, mtime) about an entry.
zip:delete
Deletes an entry from the archive.
zip:rename
Renames an entry within the archive.
zip:list
Lists all entry filenames in the archive.
<zip:archive filename="./data/export.zip">
<zip:list var="entries"/>
</zip:archive>
<foreach var="entries" var_value="name">
<output>$name&n;</output>
</foreach>
Practical ZIP Pattern: Bundling Multiple Exports
<!-- Generate reports -->
<excel:workbook>
<excel:set coords="A1">Report Data</excel:set>
<excel:create var="excel_data" format="xlsx"/>
</excel:workbook>
<pdf:document var="pdf_data" title="Report">
<pdf:section><pdf:body><pdf:block>Report PDF</pdf:block></pdf:body></pdf:section>
</pdf:document>
<!-- Bundle into ZIP -->
<zip:archive filename="./data/bundle.zip">
<zip:write filename="report.xlsx">$excel_data</zip:write>
<zip:write filename="report.pdf">$pdf_data</zip:write>
<zip:write filename="metadata.json">{"generated": "$timestamp"}</zip:write>
</zip:archive>
<!-- Serve the ZIP -->
<file:read var="zipdata" filename="./data/bundle.zip"/>
<header>Content-Type: application/zip</header>
<header>Content-Disposition: attachment; filename="reports.zip"</header>
<output>$zipdata</output>