Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Writes XLSX files. Simple, clean XML and style. Supports autofilters and headers/footers with images and page numbers if you're willing to do a little Excel hacking.
branch: master

This branch is 78 commits ahead of mumboe:master

Failed to load latest commit information.
lib Case-sensitively reference sharedStrings.xml in content_types.xml - f…
test Auto cast symbol to string
.gitignore clean up after tests
CHANGELOG Case-sensitively reference sharedStrings.xml in content_types.xml - f…
Gemfile modernize
LICENSE update license and copyright
Rakefile add basic tests
foo.rb treat "true" as true when calculating cell type
repack.rb useful tools for development
unpack.rb useful tools for development
xlsx_writer.gemspec use MurmurHash3::V128.str_digest instead of Digest::MD5 for shared st…



Writes (doesn't read or modify) XLSX files.

Imposes (non-customizable) a certain style: Arial 10pt, left-aligned text and dates, right-aligned numbers and currency

Optionally adds an autofilter.


Based on the original simple_xlsx_writer gem and patches by mumboe

Changes from simple_xlsx_writer (caution opinionated)

Then I tore it down and rebuilt it:

  • no longer constructs everything in a single zipstream... instead writes the individual files to /tmp and then zips them together
  • absolute minimum XML - went through every line, testing to see if I could remove it
  • no more block format - this was more appropriate when it was constructed as a zipstream

Features not present in simple_xlsx_writer:

  • opinionated, non-customizable styles - Arial 10pt, left-aligned text and dates, right-aligned numbers and currency
  • autofilter based on a cell range
  • header and footer, with support for images (.emf only) and page numbers
  • fits columns to text


  1. real documentation
  2. real tests

Corporate support

Faraday logo

We use xlsx_writer for marketing analytics at Faraday.


require 'xlsx_writer'

doc =

# show TRUE for true but a blank cell instead of FALSE

sheet1 = doc.add_sheet("People")

# freeze pane underneath the first (header) row
sheet1.freeze_top_left = 'A2'


  "Average citations per paper"
  Date.parse("July 31, 1912"), 
  "Milton Friedman",
  "Economist / Statistician",
  {:type => :Currency, :value => 10_000},
sheet1.add_autofilter 'A1:E1'

doc.header.right.contents = 'Corporate Reporting'
doc.footer.left.contents = 'Confidential'
doc.footer.right.contents = :page_x_of_y

# if you really need images in header/footer: do it in Excel, save, unzip the xlsx... get the .emf files, "cropleft" (if necessary), etc. from there

left_header_image = doc.add_image('image1.emf', 118, 107)
left_header_image.croptop = '11025f'
left_header_image.cropleft = '9997f'
center_footer_image = doc.add_image('image2.emf', 116, 36)
doc.header.left.contents = left_header_image = [ 'Powered by ', center_footer_image ]
doc.page_setup.header = 0
doc.page_setup.footer = 0


# You should move the file to where you want it
require 'fileutils' doc.path, 'myfile.xlsx'

# don't forget


Copyright (c) 2014 Dee Zsombor, Justin Beck, Seamus Abshere. See LICENSE for details.

Something went wrong with that request. Please try again.