# caxlsx_rails: spreadsheet templates for Rails from the Axlsx community

> caxlsx_rails is a Rails plugin that adds an xlsx format and a template handler, so a spreadsheet is built inside a view template rather than in a controller or a model. It is the maintained continuation of axlsx_rails, renamed to match the caxlsx organisation, and it supports Rails 6.1 through 8.x on Ruby 2.6 through 4.0.

**caxlsx/caxlsx_rails** — A Rails plugin to provide templates for the axlsx gem

- Repository: https://github.com/caxlsx/caxlsx_rails
- Stars: 763 · Forks: 87
- Language: Ruby
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/caxlsx-caxlsx-rails

## What the plugin adds to Rails

caxlsx_rails provides a renderer and a template handler. It adds the :xlsx format and parses .xlsx.axlsx templates, and the README explains the point of that in one sentence: it lets you take all the caxlsx code out of your controller or model and place it inside the template, where view code belongs.

That is the whole idea, and it is a small one with a large effect on how a spreadsheet export is structured. Without the plugin, a Rails controller that exports a spreadsheet has to build the workbook, serialise it and hand back the bytes, which mixes presentation logic into the controller. With it, the controller sets instance variables and responds with format.xlsx, and the template builds the workbook.

The naming is worth a note because it trips people up. The template file is named action_name.xlsx.axlsx, with the double extension, and the README warns about typos in bold.

The plugin is the continuation of a project that has been renamed. The README opens with the notice that axlsx_rails has been renamed to caxlsx_rails, so that the gem matches the other gems in the Axlsx community organisation, which is at github.com/caxlsx, and there is a Slack channel for that organisation.

The primary language is Ruby, the licence field says MIT, and the recent releases are v0.7.2 from 2026-06-18 and v0.7.1 from 2026-04-01, with the last push on 2026-06-22.

## The controller and the template

The controller side is the smallest part and it is the part that changes least.

```ruby
class ButtonController < ApplicationController
  def action_name
    @buttons = Button.all
    respond_to do |format|
      format.xlsx
    end
  end
end
```

The template side is where the spreadsheet is actually built.

```ruby
wb = xlsx_package.workbook
wb.add_worksheet(name: "Buttons") do |sheet|
  @buttons.each do |button|
    sheet.add_row [button.name, button.category, button.price]
  end
end
```

The xlsx_package variable is the handle to the package, and the README notes that all the caxlsx specific markup goes here: adding worksheets, filling content, merging cells and adding styles, with the caxlsx examples page as the reference for what is possible.

One detail that saves a surprise later: view helpers are available in the template, the same as in an erb template. That is what makes moving the code into the view a real improvement rather than a relocation, because the spreadsheet can use the same helpers the HTML view uses.

The README also points to a blog post for a more complete walkthrough, and to the older axlsx blog for the underlying gem's usage.

## Rendering options, disposition and file names

The rendering options section lists four ways to call render, and they differ in which template they pick and what file name the response carries.

```ruby
# rendered, no disposition/filename header
render 'buttons'
# rendered from another controller, no disposition/filename header
render 'featured/latest'
# template and filename of 'buttons'
render xlsx: 'buttons'
# template from another controller, filename of 'latest_buttons'
render xlsx: 'latest_buttons', template: 'featured/latest'
```

The disposition option decides whether the browser opens the file or downloads it, and the default depends on how you called render.

```ruby
render xlsx: "buttons", disposition: 'inline'
```

If render xlsx: is called, the disposition defaults to attachment. So the inline form has to be asked for explicitly.

The file name logic is the fiddliest part, and the README splits it into two cases. If Rails calls the plugin through the default channels, for example with format.xlsx, you have to set the name yourself with the response header.

```ruby
format.xlsx {
  response.headers['Content-Disposition'] = 'attachment; filename="my_new_filename.xlsx"'
}
```

If you use render xlsx:, the gem tries to guess the name from the template, and if that fails you pass the filename parameter.

```ruby
render xlsx: "action_or_template", filename: "my_new_filename.xlsx"
```

The guessing is a heuristic on the template name, so a template called something like latest_buttons produces a file name of latest_buttons, which is rarely what a user wants to receive, and the explicit parameter is the reliable route.

## Package options, partials and mailers

Three features extend the basic export, and each solves a specific problem.

The first is the package options, which are the three settings caxlsx accepts when it creates a workbook. The :xlsx_author option sets the author of the document, the :xlsx_created_at option sets the timestamp in the document properties and defaults to the current time, and the :xlsx_use_shared_strings option is a boolean passed to the workbook to say whether shared strings should be used when serialising the package. Any of them can be passed to render :xlsx or set as a local variable in the template.

```ruby
render xlsx: "index", xlsx_author: "Elmer Fudd"
render "index", locals: {xlsx_author: "Elmer Fudd"}
```

The second is partials, and the rule is that partials work as expected but you must pass in the relevant spreadsheet variables.

```ruby
wb = xlsx_package.workbook
render :partial => 'cover_sheet', :locals => {:wb => wb}
wb.add_worksheet(name: "Content") do |sheet|
  sheet.add_row ['Content']
end
```

With the partial simply using the passed variables. The practical point is that a cover sheet and the content sheet can be separate files, and the workbook is threaded through as a local.

The third is mailers, where the export is rendered to a string and attached.

```ruby
class UserMailer < ActionMailer::Base
  def export(users)
    xlsx = render_to_string layout: false, handlers: [:axlsx], formats: [:xlsx], template: "users/export", locals: {users: users}
    attachment = Base64.encode64(xlsx)
    attachments["Users.xlsx"] = {mime_type: Mime[:xlsx], content: attachment, encoding: 'base64'}
  end
end
```

The handler name in render_to_string is :axlsx rather than :xlsx, which is a leftover of the old gem name and a small trap. The README also carries a dated compatibility note about acts_as_xlsx, which is not compatible with Rails 4.1 as of 2014-04-01 and warns on 4.0, with a patched fork offered in the meantime.

## Where caxlsx_rails is the wrong choice

The first limitation is that this is a thin plugin over a specific gem, not a general spreadsheet solution. Everything it does is arranged around caxlsx, so a project that wants to write Excel files in a framework-neutral way, or one that wants a different library, gets nothing from it.

The second is the renaming. The gem was axlsx_rails and is now caxlsx_rails, and the README explains that this was to match the other gems in the Axlsx community organisation. The practical consequence is that a Gemfile line, a lockfile and any documentation referring to the old name all need changing, and the same organisation has been moving other gems between repositories, so the broader ecosystem around this gem has been reorganised too.

The third is the Ruby version range. Supported versions are 2.6, 2.7, 3.x and 4.0, which is a wide range, and it also means the gem is expected to work on a Ruby that a current Rails would not run. The Rails range is 6.1, 7.x and 8.x, so the newest Rails is covered, but the oldest supported Rails is several major versions behind.

The fourth is the acts_as_xlsx interaction, which is where the oldest rough edge is. If you use that library, the README's note about a Rails 4.1 incompatibility and a patched fork is a warning that the two libraries do not compose cleanly, and it is a dated note.

The fifth is that a spreadsheet export built this way inherits the views' own fragility. A template that raises inside the xlsx handler produces a broken download rather than an error page in some cases, and the doubled file extension is a known source of confusing failures that the README itself flags with a warning about typos.

## How caxlsx_rails compares with other spreadsheet libraries and with a plain caxlsx script

The comparison with the other Ruby spreadsheet libraries is the first one, and the difference in approach is where the code lives. Libraries such as the RubyXL-based and spreadsheet-based gems expose an API you call from a controller or a service object, and the file name, the content type and the workbook construction are all in your code. caxlsx_rails moves the workbook construction into a view and leaves the controller with a format block.

For a Rails application that exports spreadsheets regularly, that is a real structural improvement, because a spreadsheet template can then use the same helpers, the same partials and the same conventions as the HTML views, and a designer of a report can be someone who knows the views rather than someone who knows the export code.

The second comparison is with using caxlsx directly, with no Rails plugin. The README is explicit that the plugin depends on caxlsx and points to its examples for usage, so the plugin is an addition rather than an alternative. Without the plugin you can still build a workbook, but you write the response, the headers and the file name yourself in a controller, and you lose the template layer.

The third comparison is with a background job generating the file and attaching it to an email, which is what a large export looks like at scale. The mailer support here covers the simple case, and a job-based approach is a different architecture that no template plugin replaces.

The fourth comparison is with the styling libraries around caxlsx. The README points to axlsx_styler for easier styles and borders, which is the same pattern as any ecosystem: the core library is deliberately low level, and a separate gem adds the convenience layer.

## Licence, project state and what to check before you add it

The licence field on the repository says MIT, and the repository carries an MIT-LICENSE file at the root, which is the most permissive of the common licences and about as few obligations as a gem can have.

The project is not archived and the last push was on 2026-06-22, so it is being maintained, and the recent releases v0.7.2 and v0.7.1 from April and June 2026 show a steady patch cadence. The badges cover the gem version, a coverage status from Coveralls, the test workflow and the download count, which is the usual set for a gem of this age.

The repository layout is the conventional one. There is a caxlsx_rails.gemspec, a Gemfile, a Rakefile, a Guardfile, a lib/ directory with the plugin code, a spec/ directory for the tests, a CHANGELOG.md and a MIT-LICENSE file.

Four things to check before you add it.

The name. If your Gemfile says axlsx_rails, it has to become caxlsx_rails, and the version floor is Caxlsx 4.0 because the plugin depends on the current major version of the underlying gem.

The Ruby and Rails combination. The supported versions are Ruby 2.6, 2.7, 3.x and 4.0 on Rails 6.1, 7.x and 8.x, and if your application is pinned to something outside that range you will be building a gem against an untested combination.

The file name behaviour, because the default disposition is attachment and the name is guessed unless you set it, and a download called latest_buttons is a small bug you will find in a user's inbox rather than in a test.

And the acts_as_xlsx question, if you use that library, since the README's compatibility note is old and the offered workaround is a fork.

## Conclusion

caxlsx_rails suits a Rails application that exports spreadsheets and would rather keep the spreadsheet markup in a view template than in a controller, and it suits a team already using the caxlsx gem. It is the wrong tool for a non-Rails project, and the wrong choice if you need Excel features that the underlying caxlsx library does not implement. Before you upgrade, read the changelog, because the gem was renamed from axlsx_rails and the Caxlsx organisation has been moving gems between repositories, so a dependency line that says axlsx_rails needs changing rather than just bumping.

## FAQ

### What does caxlsx_rails do?

It provides a renderer and a template handler for Rails, adding the :xlsx format and parsing .xlsx.axlsx templates. That lets you build a spreadsheet inside a view template rather than in a controller or model, using the xlsx_package variable, with the same view helpers available as in an erb template.

### How do I install caxlsx_rails?

Add caxlsx and caxlsx_rails to your Gemfile. The requirements are Rails 6.1, 7.x or 8.x, Ruby 2.6, 2.7, 3.x or 4.0, and a minimum Caxlsx version of 4.0.

### How do I control the file name and disposition of the exported spreadsheet?

Calling render with the xlsx form sets the disposition to attachment by default, and you pass disposition 'inline' to open it in the browser. The file name is guessed from the template when you use render xlsx:, and you can set it explicitly with the filename parameter, or set the Content-Disposition header yourself when Rails calls the plugin through format.xlsx.

### What is the difference between caxlsx_rails and axlsx_rails?

It is a rename, announced at the top of the README, so that the gem matches the other gems in the Axlsx community organisation at github.com/caxlsx. The package description still calls it Axlsx-Rails, so a dependency on the old name has to be updated rather than simply bumped.

### Can caxlsx_rails send a spreadsheet as an email attachment?

Yes. The mailer example renders the template to a string with render_to_string using the axlsx handler and the xlsx format, base64 encodes the result and attaches it with the xlsx mime type.

### What licence does caxlsx_rails use?

MIT, with the terms in the MIT-LICENSE file at the root of the repository, and the gem is published under the caxlsx_rails name.

## Sources

- [caxlsx/caxlsx_rails on GitHub](https://github.com/caxlsx/caxlsx_rails)
- [Issues](https://github.com/caxlsx/caxlsx_rails/issues)
- [License: MIT](https://github.com/caxlsx/caxlsx_rails/blob/master/LICENSE)
- [README](https://github.com/caxlsx/caxlsx_rails/blob/master/README.md)
- [Releases](https://github.com/caxlsx/caxlsx_rails/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/caxlsx-caxlsx-rails
