Library / SDK
jmcnamara/XlsxWriter avatar
jmcnamara/XlsxWriter

XlsxWriter: writing XLSX files from Python, and where it stops

A Python module for creating Excel XLSX files.

3,978 stars674 forksPythonBSD-2-Clause

At a glance

What is it?
XlsxWriter is a write-only Python library for producing Excel 2007+ XLSX files with formatting, charts, conditional formatting and Pandas integration. It is the right tool when Python generates the spreadsheet, and the wrong one when you need to read a workbook back.
Who is it for?
Adopt XlsxWriter when Python produces the workbook and nothing reads it back: report generation, exports, chart-heavy deliverables, and Pandas or Polars pipelines that need cell formatting rather than a plain to_excel dump. Do not adopt it for reading, editing or round-tripping existing .xlsx files, and do not expect it to open a workbook, change one cell and save it; the README describes writing only, and openpyxl is the usual answer for that job.
Can I use it commercially?
Yes. BSD-2-Clause 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 57 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

What XlsxWriter is for, and who ends up using it

XlsxWriter produces Excel 2007+ XLSX files from Python. The README states the scope plainly: it writes text, numbers, formulas and hyperlinks to multiple worksheets, and supports formatting, merged cells, defined names, charts, autofilters, data validation and drop down lists, conditional formatting, images, rich multi-format strings, cell comments, textboxes and macros. It also integrates with Pandas and Polars, and offers a memory optimization mode for writing large files.

The audience is anyone whose spreadsheet is an output rather than an input. A backend service that emits a monthly financial report, a data team that hands formatted workbooks to analysts, a script that turns a query result into something a non-programmer can open. Those users care about cell formats, column widths, number formats and charts, because the file has to look finished when it lands.

The design decision that follows from this is the one that defines the library: it is write-only. There is no path in the README for opening an existing workbook, reading its cells, or modifying it in place. That single constraint decides most adoption questions, and it is why the openpyxl comparison comes up so often.

The Workbook, Worksheet and Format objects behind every file

The API is built from three kinds of object. A Workbook represents the output file. You get a Worksheet from it, and you get Format objects from it too. Writes go to the worksheet; formatting is defined once on the workbook and passed into the write call.

The README example shows the shape of it. workbook = xlsxwriter.Workbook("demo.xlsx") creates the file handle, workbook.add_worksheet() adds a sheet, and workbook.add_format({"bold": True}) creates a reusable format. Writes accept either A1 notation, as in worksheet.write("A1", "Hello"), or zero-indexed row and column numbers, as in worksheet.write(2, 0, 123). Column widths are set with worksheet.set_column("A:A", 20).

The important part is workbook.close(). Until that call, the file on disk is not the finished workbook. Everything accumulates in memory and is assembled when you close, which is also why the memory optimization mode exists as a separate way of working rather than the default. If a script crashes before close, you do not get a partial but valid XLSX; you get nothing usable. Treat close() as part of the write, not as cleanup.

The library uses standard libraries only, and the README states it supports Python 3.8+ and PyPy3. setup.py enforces that floor: it warns and exits below Python 3.8. There is no compiled extension to build and no Excel installation required on the machine doing the writing.

Installing XlsxWriter and writing a first formatted workbook

The package is on PyPI under the name xlsxwriter, so the install is a pip command. The README points to the documentation at xlsxwriter.readthedocs.io for the full API; the repository itself carries an examples/ directory with one script per feature, from array_formula.py to the chart_*.py family.

bash
pip install xlsxwriter

After that, importing xlsxwriter should succeed with no further setup. A minimal script that exercises formatting, a column width and a number format looks like this:

python
import xlsxwriter

workbook = xlsxwriter.Workbook("report.xlsx")
worksheet = workbook.add_worksheet()
worksheet.set_column("A:A", 20)
bold = workbook.add_format({"bold": True})
worksheet.write("A1", "Region", bold)
worksheet.write("A2", "North")
worksheet.write(2, 1, 1234.5, workbook.add_format({"num_format": "#,##0.00"}))
workbook.close()

Run it and report.xlsx appears in the working directory. Open it and column A is wider than default, A1 is bold, and the number in B3 carries a thousands separator. If the file is missing, the usual cause is an exception before workbook.close(), because the workbook is only written out at that point.

For a Pandas workflow, the README lists Pandas and Polars integration, and the repository ships examples for it. The pattern is to construct an ExcelWriter with the xlsxwriter engine, write the DataFrame, and apply formats through the workbook object before saving. The documentation covers the exact wiring; the README does not reproduce it.

Where XlsxWriter is the wrong tool

Write-only is a real limitation, not a footnote. If your job is to open a workbook a human maintains, update a few cells and save it, XlsxWriter cannot do it. The README describes writing files, not reading them, and nothing in the repository layout suggests a reader module. Teams that discover this late usually rewrite the step around a different library.

The second constraint is the close() boundary. Because output is assembled at close time, a long-running process that builds a large workbook holds it in memory until then. The README mentions a memory optimization mode for writing large files, which tells you the default path is not optimized for that case. If you are generating very large exports on a memory-constrained worker, that mode is the part to read before you size anything.

The third is fidelity. The README claims 100% compatible Excel XLSX files, and the project's own test suite, invoked through the Makefile, is how that claim is defended. But a generated file is still a generated file: complex formulas, pivot tables or features outside the documented set will not appear. The documentation is the authority on what is supported; if a feature is not listed there, assume it is not.

Finally, the maintenance signal. The last push to the default branch was on 2026-08-04, roughly seven weeks before this writing, and the repository is not archived. That is a live project, but the cadence is not something the README promises, so pin a version rather than tracking main.

XlsxWriter vs openpyxl: writing against round-tripping

The comparison that comes up most is XlsxWriter against openpyxl, and the difference is architectural rather than cosmetic. XlsxWriter builds a file from nothing and writes it once. openpyxl is built around loading a workbook into memory, letting you read and modify it, and saving it back. That makes openpyxl the tool for editing existing files and XlsxWriter the tool for producing new ones.

The formatting story differs in emphasis. XlsxWriter's Format objects are created on the workbook and reused across writes, which suits generating many cells with a small set of styles. Charts, conditional formatting and data validation are first-class in the README's feature list, and the examples directory has a chart script for roughly every chart type Excel offers, from chart_pareto.py to chart_gauge.py. If your deliverable is chart-heavy, that breadth is the reason to pick it.

There is also a C sibling. The repository topics list libxlsxwriter, and the related searches include Xlsxwriter C, so people arrive looking for the C library rather than the Python module. They are separate codebases with a shared author and a shared approach; installing the Python package does not give you the C library, and vice versa. If you are working in C, you want libxlsxwriter, not the pip package.

Licence, upgrade cost and what the Makefile reveals

XlsxWriter is BSD-2-Clause, stated in setup.py, in LICENSE.txt and in the Makefile's SPDX header. That is a permissive licence: it allows use in closed-source products and requires preserving the copyright notice and licence text. It is not legal advice, and if you redistribute the library inside a product, have someone check the notice requirements rather than assuming.

Upgrade cost is low by construction. The library uses standard libraries only, so there is no dependency tree to reconcile and no binary wheel to rebuild against a new interpreter. The setup.py classifiers cover Python 3.8 through 3.14, and the Makefile's testpythons target runs the suite against each of those versions. That is a strong signal that a Python upgrade will not strand you, though it is a signal about the project's testing, not a guarantee about your code.

The Makefile also shows the internal hygiene: ruff, black, pylint, isort and flake8 targets, plus a separate lint configuration for examples/. If you fork or vendor the code, that is the toolchain you would be matching. The practical upgrade advice is to pin the version in setup.py or your requirements file and read the release notes at xlsxwriter.readthedocs.io/changes.html before moving, since the README itself carries no compatibility table.

Editorial conclusion

Adopt XlsxWriter when Python produces the workbook and nothing reads it back: report generation, exports, chart-heavy deliverables, and Pandas or Polars pipelines that need cell formatting rather than a plain to_excel dump. Do not adopt it for reading, editing or round-tripping existing .xlsx files, and do not expect it to open a workbook, change one cell and save it; the README describes writing only, and openpyxl is the usual answer for that job. Before committing, verify three things against your own files: that the formula strings you write are accepted by your version of Excel or LibreOffice, that the conditional formatting rules you need are among those the documentation covers, and that your environment meets the Python 3.8 floor enforced in setup.py. Then run one real report end to end and open the result in the spreadsheet application your recipients actually use.

Frequently asked questions

Which is better, openpyxl or XlsxWriter?

It depends on direction. XlsxWriter writes new XLSX files and the README describes no way to read or modify an existing one, while openpyxl is the usual choice when you need to load a workbook, change it and save it back. If Python generates the file from scratch, XlsxWriter's formatting and chart support is the reason to pick it.

What is XlsxWriter in Python?

It is a Python module for writing files in the Excel 2007+ XLSX format. According to the README it handles text, numbers, formulas and hyperlinks across multiple worksheets, plus formatting, charts, autofilters, data validation, conditional formatting, images and cell comments.

How do I install XlsxWriter?

Install it from PyPI with pip install xlsxwriter. The package supports Python 3.8 and later, and setup.py warns and exits on older interpreters.

How to use xlsxwriter with pandas?

The README lists integration with Pandas and Polars as a supported feature, and the repository ships examples for it. The documented pattern is to create an ExcelWriter using the xlsxwriter engine, write the DataFrame, and apply formats through the workbook before saving; the README does not reproduce the full wiring, so the documentation is the place to check.

Official sources

  1. Issues
  2. jmcnamara/XlsxWriter on GitHub
  3. License: BSD-2-Clause
  4. Project website
  5. README
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/jmcnamara-xlsxwriter.svg)](https://hysenlabs.com/projects/jmcnamara-xlsxwriter)