Library / SDK
brechtsanders/xlsxio avatar
brechtsanders/xlsxio

XLSX I/O: a small C library for reading and writing spreadsheets

XLSX I/O - C library for reading and writing .xlsx files

527 stars131 forksCMIT

At a glance

What is it?
XLSX I/O is a standard C library that reads values out of .xlsx files and writes data tables back into them, with separate read and write libraries, a two-library design that keeps the dependency surface to expat and a zip library. It suits C and C++ programs that need to talk to Excel format without Excel installed, and it deliberately does not handle formulas, charts or multiple worksheets.
Who is it for?
Adopt XLSX I/O when you are writing C or C++ code that must read or write Excel data tables and you want a dependency footprint of expat plus a zip library rather than a full office document model. Do not adopt it when you need formulas, charts, formatting or multiple worksheets in the output, because the library treats the spreadsheet as a table and writes only one worksheet per file.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 29 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A spreadsheet library that treats the sheet as a table

XLSX I/O is a cross-platform C library for reading values from and writing values to .xlsx files, and the README is blunt about the model it assumes.

The Description section says the library aims to provide a C library for reading and writing .xlsx files, and that the format is the native format used by Excel since version 2007. The Goal section lists what it was written with in mind: standard C but usable from C++, a simple interface, a small footprint, portability across Windows and *nix, minimal dependencies of only expat for reading and minizip or libzip which depend on zlib in turn, a separate library for reading and for writing, and no requirement for Excel to be installed.

That last pair of constraints, the dependency list and the no-Excel requirement, are the whole reason the library exists. A .xlsx file is a zip archive of XML parts, so reading one means unzipping it and parsing XML, and the dependency set is exactly the two things that job needs.

The data model assumption is stated on both the read and write sides. For reading, the intent is to process .xlsx files as a data table, which assumes the first row contains header names, that the next rows contain values in the same columns as where the header names are supplied, and that only values are processed, with anything else ignored, including formulas, layout, graphics and charts. For writing, the intent is to write data tables as .xlsx files, with only support for writing data, no support for formulas, layout, graphics or charts, and no support for multiple worksheets, only one worksheet per file.

That is a narrow contract, and the narrowness is the point. The library is for programs that want the numbers in a spreadsheet, not for programs that want to edit a spreadsheet.

Two libraries, three read entry points, and what each buys you

The Libraries section names three artefacts, and the split tells you how the library is meant to be used.

There is `-lxlsxio_read`, the library for reading .xlsx files, which requires `#include <xlsxio_read.h>`. There is `-lxlsxio_write`, the library for writing .xlsx files, requiring `#include <xlsxio_write.h>`. And there is `-lxlsxio_readw`, an experimental library for reading .xlsx files that is linked with `-lexpatw` and requires `#define XML_UNICODE` before the include, which is the UTF-16 path.

Separating read from write is a real design decision rather than tidiness. A program that only consumes spreadsheets should not link the writing code, and the separate read and write libraries in the Goal list are how the library keeps a small footprint for consumers that need one direction only. The experimental wide-character library is separate again because it needs a different expat build, and the Makefile comment describes it as experimental and only tested on Windows.

For reading there are two methods. The simple method allows the application to iterate through rows and cells, and the advanced method has less overhead and calls callback functions for each cell and after each row. The callback form is the one that matters for large files, because the simple iterator form is where per-cell function call overhead adds up.

Two memory characteristics are worth knowing. The entire shared string table is loaded into memory, with the README warning that this could be large for big spreadsheets with a lot of different values, and the library also supports .xlsx files without a shared string table. The worksheet data itself is read on the fly without the need to buffer it in memory.

Building it: make, CMake, Conan, and the zip library choice

The build is documented in three ways, and the third is the quickest route for a lot of projects.

The requirements are a C compiler such as gcc or clang, with MinGW and MinGW-w64 supported on Windows, the dependency libraries, a shell environment with MSYS supported on Windows, the make command, and CMake 2.6 or higher, which is optional but preferred. There are two build methods, the basic Makefile included in the repository and CMake, with CMake marked as the preferred method.

The CMake route configures with `cmake -G"Unix Makefiles"`, or `cmake -G"MSYS Makefiles"` on Windows, followed by options that switch off parts of the build:

bash
  + `-DBUILD_STATIC:BOOL=OFF` - Don't build static libraries
  + `-DBUILD_SHARED:BOOL=OFF` - Don't build shared libraries
  + `-DBUILD_TOOLS:BOOL=OFF` - Don't build tools (only libraries)
  + `-DBUILD_EXAMPLES:BOOL=OFF` - Don't build examples
  + `-DWITH_LIBZIP:BOOL=ON` - Use libzip instead of Minizip

with paths for `-DLIBZIP_DIR:PATH` and `-DMINIZIP_DIR:PATH` and a `-DWITH_WIDE:BOOL=ON` switch to also build the UTF-16 library. The build and install then runs `make install`, or `make install/strip` to strip symbols.

The Makefile route has its own parameter set, including `PREFIX=<path>`, `WITH_LIBZIP=1`, `WIDE=1` and `STATICDLL=1`, where the last builds a static DLL that does not depend on any other DLLs and is only supported on Windows.

The third option is Conan, and it is a single command:

bash
conan install --requires="xlsxio/[*]" --build=missing

The README says the Conan recipe is kept up to date by Conan maintainers and community contributors, and asks for an issue or pull request on the ConanCenterIndex repository if the version is out of date.

The dependency choice deserves attention. The README says minizip is preferred, as there have been reports that .xlsx files generated with XLSX I/O built against libzip cannot be opened with LibreOffice. That is a concrete interoperability warning, and the Makefile reflects the choice with a `-DUSE_MINIZIP` versus `-DUSE_LIBZIP` define.

Reading a file, and the two command line tools

The example program for reading shows the shape of the API, and the opening is short enough to quote.

c
//open .xlsx file for reading
xlsxioreader xlsxioread;
if ((xlsxioread = xlsxioread_open(filename)) == NULL) {
  fprintf(stderr, "Error opening .xlsx file\n");
  return 1;
}

The header to include is `#include <xlsxio_read.h>`, and the example files in the repository show the rest: `example_xlsxio_read.c`, `example_xlsxio_read_advanced.c`, `example_xlsxio_write.c`, `example_xlsxio_write_getversion.c`, plus C++ versions `example_xlsxio_read_cpp.cpp` and `example_xlsxio_write_cpp.cpp`. The C++ files exist because the Goal list says the library is written in standard C but allows being used by C++.

There are also two command line utilities included with the project. `xlsxio_xlsx2csv` converts all sheets in all specified .xlsx files to individual CSV files, and `xlsxio_csv2xlsx` converts all specified CSV files to .xlsx files.

Those two tools are worth reading as a specification of the library's behaviour, because the first one converts all sheets while the write side only supports one worksheet per file. In other words the tools are not a round trip: a multi-sheet workbook becomes multiple CSV files, and those CSVs cannot be recombined into a single multi-sheet .xlsx by the write side. Anyone reaching for these utilities hoping to round trip a workbook will not get one.

Where XLSX I/O is the wrong tool

The first wrong-tool case is a spreadsheet that is a document rather than a table. The library ignores formulas, layout, graphics and charts on read, and writes none of them. If the file you have to read has values that are computed by formulas, the library will not evaluate them, and if the file you have to write needs formatting, merged cells or more than one sheet, the write side cannot produce it.

The second is the memory profile of the shared string table. The whole table is loaded into memory on read, and the README itself warns that this could be large for big spreadsheets with a lot of different values. A file with a hundred thousand distinct strings is a hundred thousand strings resident at once, and a workbook exported from a large catalogue is exactly that shape. The worksheet rows themselves stream, but the string table does not, so the memory behaviour is uneven in a way that is easy to underestimate.

The third is a multi-sheet output requirement. One worksheet per file is the hard limit, and as the command line utilities show, the read side is more capable than the write side, so a round trip loses structure.

The fourth is a managed environment where you cannot install native dependencies. The library needs expat and a zip library with zlib, and while Conan smooths the packaging, it is still a native build.

The alternative worth naming is reading the file as a zip archive and parsing the sheet XML yourself, which is what many people do before this library existed, and the difference in approach is that XLSX I/O has already done the tedious parts, the archive handling, the relationship parsing and the shared string resolution, and gives you a simple cell iteration API. The other alternative is a higher-level library in another language, which gives you a richer object model and a much larger dependency footprint, and the trade there is convenience and scope against a small footprint in standard C.

Maintenance, portability and the licence

The last push to the default branch was on 2026-09-24, the same day as release 0.2.37, and the previous two releases were 0.2.36 on 2025-09-12 and 0.2.35 on 2024-03-28. The repository is not archived, and the version numbering has stayed on the 0.2 line across all three of those tags, so the project is in a steady, low-churn state rather than a rapid one.

That steadiness is a fair trade for what this library is. A spreadsheet reader that has been stable for years is a dependency you can build against without expecting the API to move under you, and the repository layout supports the claim of an actively maintained, properly packaged project. There is a `CMake/` directory, a `build/` directory, a `doc/` directory, an `examples/` directory, `include/`, `lib/` and `src/`, a `Changelog.txt`, a `LICENSE.txt`, and a `template.pc.in` for pkg-config along with `templateConfig.cmake.in` and `templateConfigVersion.cmake.in` for CMake package config generation. The `buildbin.sh` script and the `.travis.yml` file are older continuous integration artefacts, which is a hint about the age of the build tooling compared with the CMake path.

Prebuilt binaries are offered for Windows 32-bit and 64-bit, both built with MinGW-w64 under an MSYS2 shell, and the README explains that to link against the DLLs from Microsoft Visual C++ you need a.lib file for each DLL, generated with the `lib` tool, with the exact commands given for 32-bit and 64-bit.

The licence is MIT, with the licence text in `LICENSE.txt` at the top of the tree. For a library that is vendored into other programs, MIT is the most straightforward arrangement available, with the only obligation being to keep the copyright notice, and no requirement to publish anything about your own project. This is a description of the published terms and not legal advice.

The portability claim is broad and specific at once: the library works on Windows, macOS and Linux, and the Makefile reflects that with the platform-specific extension handling, `.dll` on Windows, `.dylib` on Darwin and `.so` elsewhere, and a `-O3` default optimisation level.

Editorial conclusion

Adopt XLSX I/O when you are writing C or C++ code that must read or write Excel data tables and you want a dependency footprint of expat plus a zip library rather than a full office document model. Do not adopt it when you need formulas, charts, formatting or multiple worksheets in the output, because the library treats the spreadsheet as a table and writes only one worksheet per file. Before you build on it, decide between minizip and libzip, since the README reports that files generated against libzip have failed to open in LibreOffice, confirm the shared string table behaviour for your file sizes because the entire table is loaded into memory on read, and check whether your build needs the experimental UTF-16 library, which the Makefile describes as tested only on Windows.

Frequently asked questions

What is XLSX I/O and what does it do?

It is a cross-platform C library for reading values from and writing values to .xlsx files, the native Excel format since 2007. It treats spreadsheets as data tables, so formulas, layout, graphics and charts are ignored on read and unsupported on write, and it does not require Excel to be installed.

What dependencies does XLSX I/O need?

Only expat for reading, and minizip or libzip, which depend on zlib, for both reading and writing. The README says minizip is preferred, since there have been reports that files generated with XLSX I/O built against libzip cannot be opened with LibreOffice.

How do I build and install XLSX I/O?

The preferred route is CMake, configured with `cmake -G"Unix Makefiles"` or `cmake -G"MSYS Makefiles"` on Windows, with options such as `-DBUILD_TOOLS:BOOL=OFF` to skip the tools, then `make install`. A basic Makefile is also included, and Conan offers a one-command path with `conan install --requires="xlsxio/[*]" --build=missing`.

Can I install XLSX I/O without building it?

Prebuilt binaries are available for Windows 32-bit and 64-bit, built with MinGW-w64 under MSYS2, and Conan can install pre-built binaries as well as build from source. The README also notes that linking against the DLLs from Microsoft Visual C++ needs a .lib file for each DLL, generated with the `lib` tool.

What licence is XLSX I/O released under?

MIT, with the licence text in `LICENSE.txt` at the top of the repository. The project is MIT licensed with a `LICENSE.txt` file and the package is also distributed through Conan under the `xlsxio` recipe.

Official sources

  1. brechtsanders/xlsxio on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/brechtsanders-xlsxio.svg)](https://hysenlabs.com/projects/brechtsanders-xlsxio)

Was this useful?