Create Excel files using JavaScript without all the fuss
At Dixie we are working with financial data, and a lot of our customers need the ability to easily export and work with these data. The de-facto tool to do advanced work with numeric data is Excel. That should be easy to support, we thought. “Let’s build CSV export and unicorns will dance on the clouds,” we said. “Not so fast,” screamed Excel, “you know there’s no universal CSV standard, right?”
And hell broke lose.
I am certainly over-dramatizing here, but the problem is that there isn’t just one universal Excel-supported CSV format. Various version of Excel would expect different encoding, field delimiters, number formats, etc.
We recognize that users can import CSV into a spreadsheet, specifying delimiters and such in a wizard. But we’re always striving to make our software support our customers, so we wanted their data to be one click away.
Based on these drawbacks we decided to take the road down Excel Av. and build XLSX export from our web app.
Implementation time
We had a very simple set of requirements:
XLS or XLSX
Since we decided that CSV wasn’t good enough, XLS or XLSX would be the way to go. XLSX would be preferable, since it’s spec is open sourced and supported widely.
No server
We’ve already downloaded and rendered the data that the user are about to download. Thus we decided to avoid doing another HTTP request and look to build the XLSX file on client side.
Minor bundle size
Doing stuff like this on the client means that they have to download more code, in order to build the file they’re about to download. While we’re utilizing load-on-demand through code-splitting, we still wanted to keep the bundle size hit low.
Looking for a XLSX JavaScript lib, which works in browsers appeared to be a challenging task. We found one lib, js-xlsx, which touted browser support, but found that it was simply too large for our need. It looks like a solid lib, but with way too many features than we needed.
So we abandoned this search and decided to research the ability to simply build the XLSX ourselves.
It seemed like a straight-forward task. We’re working with an open source technology, so we assumed that a specification would be easy to find and follow. We quickly learned that we had been naive with this regard.
XLSX is not easy to find a complete and easy to digest specification of.
We looked a placed, but never really found a quick guide to the basics of a XLSX document structure. So after having spent a few days in the blind, we decided to reverse-engineer the XLSX structure. With the knowledge that a XLSX file was simply a zip archive, we unzipped it and looked into the various files and folders.
From this surgery and trial and error, we could conclude which files are required for a XLSX file to be valid. It could be constrained to only 5 files:
- [Content_Types].xml
- _rels/.rels
- xl/_rels/workbook.xml.rels
- xl/workbook.xml
- xl/worksheets/sheet1.xml
You’ll never believe what happened next. We found the actual documentation of the XML structure! It’s true, it’s right here: … Microsoft knows documentations, they’ve got the best documentations. Right.
Why am I writing all of this?
Well, we thought that we couldn’t be the only ones, who wanted to have a simple way to export data from JavaScript to Excel. So we build a little library and have open sourced it. We named it zipcelx.
It is lightweight (7kb) and simple.
It has one API: generateAndDownloadXlsx(config)
where config
is an object like this:
{
filename: 'general-ledger-Q1',
sheet: {
data: [
[{
value: 'Income - Webshop',
type: 'string'
}, {
value: 1000,
type: 'number'
}]
]
}
}
Sheet data is basically a matrix representing the cells in a spreadsheet; an array or rows, containing an array of cells.
We currently support two data types: string and number. They’re the essentials to spreadsheets.
Closing remarks
We build this pretty swiftly, but we are quite confident with it. But do feel free to leave any suggestions, comments or questions in a GitHub issue.