Caxlsx writes real xlsx files from Ruby, charts and all
xlsx generation with charts, images, automated column width, customizable styles and full schema validation. Axlsx excels at helping you generate beautiful Office Open XML Spreadsheet documents without having to understand the entire ECMA specification. Check out the README for some examples of how easy it is. Best of all, you can validate your xlsx file before serialization so you know for sure that anything generated is going to load on your client's machine.
At a glance
- What is it?
- Caxlsx is the community continued version of the Axlsx gem, a Ruby library for generating Office Open XML spreadsheets with charts, styles, images, pivot tables and schema validation before serialization. It is the pragmatic choice for a Rails app that has to hand a user a formatted workbook rather than a CSV.
- Who is it for?
- Adopt Caxlsx if your Ruby or Rails application has to deliver a formatted Excel workbook, and you want charts, styling and workbook features without assembling OOXML parts by hand. Do not adopt it if you only need to hand over tabular data, where a CSV export is simpler and avoids a dependency, and check the encryption story first, because workbook level encryption requires the separate ooxml_crypt gem, which the README says only supports MRI Ruby.
- 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 4 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A fork that outlived its original
Caxlsx is the community continued version of Axlsx, and the first section of the README is about governance rather than features. It says that to better maintain the Axlsx ecosystem, all related gems have been forked or moved to a community organisation, and it points at the github.com/caxlsx organisation as the new home. There is a Slack channel for the project, and the badges show a test workflow, a RuboCop workflow and a gem version badge.
That matters because Axlsx was a well known Ruby gem for generating xlsx files, and the community fork is what now carries the maintenance. The repository layout shows a conventional gem: an axlsx.gemspec, a lib/ directory, an examples/ directory that is very large, a test/ directory, a Rakefile, a .rubocop.yml with a .rubocop_todo.yml beside it, and YARD configuration through .yardopts.
The library's stated purpose is generating Office Open XML Spreadsheet documents without having to understand the entire ECMA specification, which is the actual value proposition. The xlsx format is a zip of XML parts with a strict schema, and the alternative to learning that schema is to generate files through a library that has already absorbed it.
The audience is Ruby and Rails developers producing reports, and the plugin list at the end of the README confirms the shape of that audience: ActiveRecord integration, a Rails renderer, an Active Admin plugin. The licence is MIT, and the most recent release in the history is v4.5.0 from 2026-06-09, with v4.4.2 from 2026-03-23 and v4.4.1 from 2025-12-03 before it. The last push was on 2026-10-19.
Everything in the package is a block you fill in
The API shape is the same in most Ruby builder libraries, and it is worth reading once because it applies to every feature. You construct a package, open a block, and inside the block you add worksheets, rows, charts and styles, then serialize.
The README's teaser does exactly that:
Axlsx::Package.new do |p|
p.workbook.add_worksheet(:name => "Pie Chart") do |sheet|
sheet.add_row ["Simple Pie Chart"]
%w(first second third).each { |label| sheet.add_row [label, rand(24)+1] }
sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,5], :end_at => [10, 20], :title => "example 3: Pie Chart") do |chart|
chart.add_series :data => sheet["B2:B4"], :labels => sheet["A2:A4"], :colors => ['FF0000', '00FF00', '0000FF']
end
end
p.serialize('simple.xlsx')
endSeveral design decisions are visible in those lines. The chart is added to a worksheet, not to the workbook, and it positions itself with a start and an end cell. The chart series does not hold data directly, it references worksheet ranges through the A1 notation, so the sheet and the chart stay in sync. The series carries explicit colours. And the output is a file on disk, p.serialize writing simple.xlsx.
The A1 style references are a first class feature of the library, listed in the feature list as item 8: reference cells with A1 and A1:D4 style references, or from the workbook with Sheet1!A3:B4 style references. That is the idiom to learn first, because everything else in the library composes with it.
The workbook is the parent object throughout, and a package can hold several worksheets. Defined names, which give repeated header rows for printing, are supported at the workbook level, and the list also covers sheet headers and footers, page breaks, margins and print options.
Charts and styles without hand written XML
The feature list is long, but two entries carry most of the weight.
The first is chart generation. Caxlsx generates 3D pie, line, scatter and bar charts, and the claim is that chart generation and management is a matter of a few lines of code. You can build a chart from data already in the worksheet, or generate one with no data in the sheet at all. Gridlines, label rotation and series colours are all customisable, and the list also includes data labels for charts and series colour customisation, plus an examples file per chart type, from 3d_line_chart_example.md to bar_chart_example.md.
The second is custom styles. The README claims guaranteed document validity while letting you style borders, alignment, fills, fonts and number formats in a single line of code, and those styles can be applied to an entire row or to a single cell anywhere in the workbook. There is a dedicated style reference in the docs directory and an append_styles_example.md in the examples folder. Cell level style overrides for default and customised style objects are supported as well.
Two features that save real time are listed almost as an aside. Column widths can be determined automatically from the content in the worksheet, or set to any value you specify, and data types are inferred too: Float, Integer, String, Date, Time and Boolean are identified and serialised automatically, with an automatic_data_types_example.md to show it.
The rest of the list covers the unglamorous parts of a real report: formulas, merged cells, row and column outlining, cell level data validation, auto filtering through worksheet.auto_filter, support for Tables, comments, conditional formatting, pivot tables, defined names, and adding jpg, gif and png images to worksheets with hyperlinks.
Two details deserve attention. The 1904 and 1900 date epochs are configurable in the workbook, which matters if you are reconciling dates from a Mac origin. And export can use shared strings or inline strings, the latter to interoperate with iWork Numbers, though the README notes that charts are not supported in that mode.
Formulas are escaped unless you say otherwise
The security section is short and it is the part of the README that should shape your configuration.
To prevent formula injection vulnerabilities, the CSV injection page of the OWASP is the reference, and as of version 4.0 axlsx escapes all formulas by default. That means a cell whose content begins with a formula is written as text rather than evaluated by Excel.
The risk being mitigated is the classic one. A report exports a database value that a user controlled, the value starts with a plus, a minus, an equals sign or an at sign, and a spreadsheet application treats it as a formula when the recipient opens the file. If a user can put a formula in a name field, they can craft a file that runs commands when the analyst double clicks it. Escaping by default closes that hole without you having to remember to close it.
The opt out is per cell:
cell.escape_formulas = falseAnd the README says the setting can be applied at the workbook, worksheet, row or cell level, with a reference to examples/escape_formula.md. The granularity is the point. If one column in your report is genuinely a formula, you disable escaping for that cell rather than for the whole export.
The practical advice is to leave the default alone for most work, and to be deliberate about any cell where you intend a formula rather than a value, because a formula you write by hand and a formula a user typed into a form look identical in the data.
Installing the gem and getting the docs running locally
Installation is a Gemfile entry:
gem 'caxlsx'The supported Ruby versions are stated plainly: Caxlsx supports Ruby 2.6 and newer. If your application is on an older Ruby, that is the first thing to check.
The documentation is published on rubydoc.info, and the README points at it plus a set of extra references: the examples folder, a FAQ that is marked as work in progress, a style reference, and a page on header and footer codes.
If you want to read the docs against the local source rather than the published site, the README gives a two step recipe:
gem install webrick
yard serverThe webrick gem is installed because the Ruby versions that dropped it from the standard library no longer bundle it, and yard server serves the generated API documentation locally.
The repository also tells you where not to ask questions. There is a prominent note that you should not create issues for usage questions about axlsx or caxlsx, and that you should look through the README, the examples folder and the FAQ instead, and check the axlsx questions on Stack Overflow. You are invited to add your question, and an answer if you have one, to the FAQ if it is of general interest.
That is a deliberate choice about where support lives, and it has a cost. The FAQ is explicitly work in progress, so the answer to an unusual question is likely to be in the examples folder or on Stack Overflow rather than in the project.
The ecosystem around it, and where the edges are
The plugin list is where Caxlsx meets the frameworks people actually use. acts_as_caxlsx provides simple ActiveRecord integration, so a model can render a worksheet from its records. caxlsx_rails provides a .axlsx renderer to Rails, which the README describes as the way to move spreadsheet code out of a controller into view files. activeadmin-caxlsx is an Active Admin plugin with a DSL for downloadable reports. And ooxml_crypt is required to enable workbook encryption and password protection.
That last one is a real constraint, and the README states it: workbook level encryption and password protection requires the ooxml_crypt gem, which only supports MRI Ruby. So if your deployment target is a JRuby runtime, encrypted workbooks are not on the table. Sheet level password and non-password protection are separate features and are listed separately from the workbook level encryption, so read the distinction carefully before promising an encrypted workbook to a customer.
Interoperability is described in deliberately modest terms. The feature list claims first stage interoperability support for GoogleDocs, LibreOffice and Numbers, and the inline string export path exists specifically for iWork Numbers, sans charts. Those are honest hedges, not guarantees, and the phrase first stage tells you the testing has not been exhaustive.
So the boundary of this library is clear. It is a strong generator for a well formatted workbook with charts and styles, and it is a weak bet if your requirement is a file that is guaranteed to render identically in every spreadsheet application on earth, or if you need encryption on a non MRI Ruby.
When a CSV is the better answer
The alternative worth naming is not another gem, it is the simplest format that could possibly work. If the requirement is a list of rows that someone opens in a spreadsheet, a CSV export is a fraction of the work: no gem dependency, no schema, no validation, and a file that every spreadsheet application reads.
The difference in approach is what you give up. A CSV has one table, no charts, no styling, no merged cells, no print setup, no conditional formatting, no pivot tables and no formulas. The moment a report has to look like something rather than be readable, or has to carry a chart into a board meeting, that simplicity becomes a limitation, and Caxlsx is the difference between a maintained report and a pile of formatting work.
There is also a middle path inside the ecosystem. If you are in Rails, the caxlsx_rails renderer lets you keep the layout in view files rather than in a controller, and activeadmin-caxlsx gives you a report DSL without writing a template at all. Both are cheaper than hand-rolling a package in a controller, and both are documented by the same community organisation that now maintains the core gem.
The decision therefore comes down to what the recipient does with the file. Data that will be filtered and pivoted by the recipient, or a document that has to carry formatting and charts, is what Caxlsx is for. Data that only has to be readable is better served by a CSV, and a library that gives you schema validation, a chart API and a styling DSL for that job is a library doing more work than the problem needs.
Editorial conclusion
Adopt Caxlsx if your Ruby or Rails application has to deliver a formatted Excel workbook, and you want charts, styling and workbook features without assembling OOXML parts by hand. Do not adopt it if you only need to hand over tabular data, where a CSV export is simpler and avoids a dependency, and check the encryption story first, because workbook level encryption requires the separate ooxml_crypt gem, which the README says only supports MRI Ruby. Before you start, confirm the Ruby version, note that the FAQ is still work in progress, and plan for the fact that formulas are escaped by default since version 4.0.
Frequently asked questions
How do I install Caxlsx in a Ruby project?
Add `gem 'caxlsx'` to your Gemfile. The README states that Caxlsx supports Ruby 2.6 and newer.
How do I create a chart in a Caxlsx worksheet?
Add a chart to a worksheet with add_chart, giving a chart class such as Axlsx::Pie3DChart, a start and end cell and a title, then add a series that references worksheet ranges with A1 notation, for example sheet["B2:B4"] for data and sheet["A2:A4"] for labels.
Does Caxlsx protect against formula injection?
Yes. As of version 4.0 the library escapes all formulas by default, and you can set escape_formulas to false per cell, row, worksheet or workbook when a cell is meant to contain a formula.
Can Caxlsx encrypt a generated workbook?
Workbook level encryption and password protection are supported, but they require the separate ooxml_crypt gem, and the README says that gem only supports MRI Ruby. Sheet level password protection is listed as a separate feature.
Official sources
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.
[](https://hysenlabs.com/projects/caxlsx-caxlsx)Was this useful?