{"id":13463195,"url":"https://github.com/roo-rb/roo","last_synced_at":"2025-05-13T16:04:45.560Z","repository":{"id":2663156,"uuid":"3654364","full_name":"roo-rb/roo","owner":"roo-rb","description":"Roo provides an interface to spreadsheets of several sorts.","archived":false,"fork":false,"pushed_at":"2025-04-07T02:33:03.000Z","size":6881,"stargazers_count":2824,"open_issues_count":118,"forks_count":504,"subscribers_count":64,"default_branch":"master","last_synced_at":"2025-05-06T00:38:32.471Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/roo-rb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2012-03-07T22:31:18.000Z","updated_at":"2025-04-30T19:38:12.000Z","dependencies_parsed_at":"2023-10-21T00:00:08.315Z","dependency_job_id":"df0871f6-ed8f-40a6-9a5a-d0d34072a46a","html_url":"https://github.com/roo-rb/roo","commit_stats":{"total_commits":902,"total_committers":152,"mean_commits":5.934210526315789,"dds":0.6962305986696231,"last_synced_commit":"3d24c117fd1c4f58826b71211526dac46d34f1c6"},"previous_names":["empact/roo"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roo-rb%2Froo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roo-rb%2Froo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roo-rb%2Froo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roo-rb%2Froo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roo-rb","download_url":"https://codeload.github.com/roo-rb/roo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252663618,"owners_count":21784788,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T13:00:47.748Z","updated_at":"2025-05-13T16:04:45.524Z","avatar_url":"https://github.com/roo-rb.png","language":"Ruby","readme":"# Roo\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/roo-rb/roo/ruby.yml?style=flat-square)](https://travis-ci.org/roo-rb/roo) [![Maintainability](https://api.codeclimate.com/v1/badges/be8d7bf34e2aeaf67c62/maintainability)](https://codeclimate.com/github/roo-rb/roo/maintainability) [![Coverage Status](https://img.shields.io/coveralls/roo-rb/roo.svg?style=flat-square)](https://coveralls.io/r/roo-rb/roo) [![Gem Version](https://img.shields.io/gem/v/roo.svg?style=flat-square)](https://rubygems.org/gems/roo)\n\nRoo implements read access for all common spreadsheet types. It can handle:\n* Excel 2007 - 2013 formats (xlsx, xlsm)\n* LibreOffice / OpenOffice.org formats (ods)\n* CSV\n* Excel 97, Excel 2002 XML, and Excel 2003 XML formats when using the [roo-xls](https://github.com/roo-rb/roo-xls) gem (xls, xml)\n* Google spreadsheets with read/write access when using [roo-google](https://github.com/roo-rb/roo-google)\n\n## Installation\n\nInstall as a gem\n\n    $ gem install roo\n\nOr add it to your Gemfile\n\n```ruby\ngem \"roo\", \"~\u003e 2.10.0\"\n```\n## Usage\n\n### Opening a spreadsheet\n\nYou can use the `Roo::Spreadsheet` class so `roo` automatically detects which [parser class](https://github.com/roo-rb/roo/blob/master/lib/roo.rb#L17) to use for you.\n```ruby\nrequire 'roo'\n\nfile_name = './new_prices.xlsx'\nxlsx = Roo::Spreadsheet.open(file_name)\nxlsx.info\n# =\u003e Returns basic info about the spreadsheet file\n```\n\n``Roo::Spreadsheet.open`` can accept both string paths and ``File`` instances. Also, you can provide the extension of the file as an option: \n\n```ruby\nrequire 'roo'\n\nfile_name = './rails_temp_upload'\nxlsx = Roo::Spreadsheet.open(file_name, extension: :xlsx)\nxlsx.info\n# =\u003e Returns basic info about the spreadsheet file\n```\n\nOn the other hand, if you know what the file extension is, you can use the specific parser class instead:\n```ruby\nrequire 'roo'\n\nxlsx = Roo::Excelx.new(\"./new_prices.xlsx\")\nxlsx.info\n# =\u003e Returns basic info about the spreadsheet file\n```\n\n### Working with sheets\n\n```ruby\nods.sheets\n# =\u003e ['Info', 'Sheet 2', 'Sheet 3']   # an Array of sheet names in the workbook\n\nods.sheet('Info').row(1)\nods.sheet(0).row(1)\n\n# Set the last sheet as the default sheet.\nods.default_sheet = ods.sheets.last\nods.default_sheet = ods.sheets[2]\nods.default_sheet = 'Sheet 3'\n\n# Iterate through each sheet\nods.each_with_pagename do |name, sheet|\n  p sheet.row(1)\nend\n```\n\n### Accessing rows and columns\n\nRoo uses Excel's numbering for rows, columns and cells, so `1` is the first index, not `0` as it is in an ``Array``\n\n```ruby\nsheet.row(1)\n# returns the first row of the spreadsheet.\n\nsheet.column(1)\n# returns the first column of the spreadsheet.\n```\n\nAlmost all methods have an optional argument `sheet`. If this parameter is omitted, the default_sheet will be used.\n\n```ruby\nsheet.first_row(sheet.sheets[0])\n# =\u003e 1             # the number of the first row\nsheet.last_row\n# =\u003e 42            # the number of the last row\nsheet.first_column\n# =\u003e 1             # the number of the first column\nsheet.last_column\n# =\u003e 10            # the number of the last column\n```\n\n#### Accessing cells\n\nYou can access the top-left cell in the following ways\n\n```ruby\nsheet.cell(1,1)\nsheet.cell('A',1)\nsheet.cell(1,'A')\nsheet.a1\n\n# Access the second sheet's top-left cell.\nsheet.cell(1,'A',sheet.sheets[1])\n```\n\n#### Querying a spreadsheet\nUse ``each`` to iterate over each row.\n\nIf each is given a hash with the names of some columns, then each will generate a hash with the columns supplied for each row.\n\n```ruby\nsheet.each(id: 'ID', name: 'FULL_NAME') do |hash|\n  puts hash.inspect\n  # =\u003e { id: 1, name: 'John Smith' }\nend\n```\n\nUse ``sheet.parse`` to return an array of rows. Column names can be a ``String`` or a ``Regexp``.\n\n```ruby\nsheet.parse(id: /UPC|SKU/, qty: /ATS*\\sATP\\s*QTY\\z/)\n# =\u003e [{:id =\u003e 727880013358, :qty =\u003e 12}, ...]\n```\n\nUse the ``:headers`` option to include the header row in the parsed content.\n\n```ruby\nsheet.parse(headers: true)\n```\n\nUse the ``:header_search`` option to locate the header row and assign the header names.\n\n```ruby\nsheet.parse(header_search: [/UPC*SKU/,/ATS*\\sATP\\s*QTY\\z/])\n```\n\nUse the ``:clean`` option to strip out control characters and surrounding white space.\n\n```ruby\nsheet.parse(clean: true)\n```\n\n#### Options\n\nWhen opening the file you can add a hash of options.\n\n##### expand_merged_ranges\nIf you open a document with merged cells and do not want to end up with nil values for the rows after the first one.\n```ruby\nxlsx = Roo::Excelx.new('./roo_error.xlsx', {:expand_merged_ranges =\u003e true})\n```\n\n### Exporting spreadsheets\nRoo has the ability to export sheets using the following formats. It\nwill only export the ``default_sheet``.\n\n```ruby\nsheet.to_csv\nsheet.to_matrix\nsheet.to_xml\nsheet.to_yaml\n```\n\nSpecify the file as default argument for `#to_csv`:\n\n```ruby\nsheet.to_csv(File.new(\"/dev/null\"))\n```\n\nspecify the custom separator:\n\n```ruby\nsheet.to_csv(separator: \":\") # \",\" using by default\n```\n\n### Excel (xlsx and xlsm) Support\n\nStream rows from an Excelx spreadsheet.\n\n```ruby\nxlsx = Roo::Excelx.new(\"./test_data/test_small.xlsx\")\nxlsx.each_row_streaming do |row|\n  puts row.inspect # Array of Excelx::Cell objects\nend\n```\n\nBy default blank cells will be excluded from the array. To keep them, use the option pad_cells = true. (They will be set to nil in the array)\n```ruby\nxlsx.each_row_streaming(pad_cells: true) do |row|\n  puts row.inspect # Array of Excelx::Cell objects\nend\n```\n\nTo stream only some of the rows, you can use the ```max_rows``` and ```offset```options.\n```ruby\nxlsx.each_row_streaming(offset: 1) do |row| # Will exclude first (inevitably header) row\n  puts row.inspect # Array of Excelx::Cell objects\nend\n```\n\n```ruby\nxlsx.each_row_streaming(max_rows: 3) do |row| # Will yield 4 rows (it's automatically incremented by 1) after the supplied offset.\n  puts row.inspect # Array of Excelx::Cell objects\nend\n```\n\nIterate over each row\n\n```ruby\nxlsx.each_row do |row|\n  ...\nend\n```\n\n``Roo::Excelx`` also provides these helpful methods.\n\n```ruby\nxlsx.excelx_type(3, 'C')\n# =\u003e :numeric_or_formula\n\nxlsx.cell(3, 'C')\n# =\u003e 600000383.0\n\nxlsx.excelx_value(row,col)\n# =\u003e '600000383'\n\nxlsx.formatted_value(row,col)\n# =\u003e '0600000383'\n```\n\n``Roo::Excelx`` can access celltype, comments, font information, formulas, hyperlinks and labels.\n\n```ruby\nxlsx.comment(1,1, ods.sheets[-1])\nxlsx.font(1,1).bold?\nxlsx.formula('A', 2)\n```\n\n### OpenOffice / LibreOffice Support\n\nRoo::OpenOffice has support for encrypted OpenOffice spreadsheets.\n\n```ruby\n# Load an encrypted OpenOffice Spreadsheet\nods = Roo::OpenOffice.new(\"myspreadsheet.ods\", password: \"password\")\n```\n\n``Roo::OpenOffice`` can access celltype, comments, font information, formulas and labels.\n\n```ruby\nods.celltype\n# =\u003e :percentage\n\nods.comment(1,1, ods.sheets[-1])\n\nods.font(1,1).italic?\n# =\u003e false\n\nods.formula('A', 2)\n```\n\n### CSV Support\n\n```ruby\n# Load a CSV file\ncsv = Roo::CSV.new(\"mycsv.csv\")\n```\n\nBecause Roo uses the standard CSV library, you can use options available to that library to parse csv files. You can pass options using the ``csv_options`` key.\n\nFor instance, you can load tab-delimited files (``.tsv``), and you can use a particular encoding when opening the file.\n\n\n```ruby\n# Load a tab-delimited csv\ncsv = Roo::CSV.new(\"mytsv.tsv\", csv_options: {col_sep: \"\\t\"})\n\n# Load a csv with an explicit encoding\ncsv = Roo::CSV.new(\"mycsv.csv\", csv_options: {encoding: Encoding::ISO_8859_1})\n```\n\nYou can also open csv files through the Roo::Spreadsheet class (useful if you accept both CSV and Excel types from a user file upload, for example).\n\n```ruby\n# Load a spreadsheet from a file path\n# Roo figures out the right parser based on file extension\nspreadsheet = Roo::Spreadsheet.open(csv_or_xlsx_file)\n\n# Load a csv and auto-strip the BOM (byte order mark)\n# csv files saved from MS Excel typically have the BOM marker at the beginning of the file\nspreadsheet = Roo::Spreadsheet.open(\"mycsv.csv\", { csv_options: { encoding: 'bom|utf-8' } })\n```\n\n## Upgrading from Roo 1.13.x\nIf you use ``.xls`` or Google spreadsheets, you will need to install ``roo-xls`` or ``roo-google`` to continue using that functionality.\n\nRoo's public methods have stayed relatively consistent between 1.13.x and 2.0.0, but please check the [Changelog](https://github.com/roo-rb/roo/blob/master/CHANGELOG.md) to better understand the changes made since 1.13.x.\n\n\n\n## Contributing\n### Features\n1. Fork it ( https://github.com/roo-rb/roo/fork )\n2. Install it (`bundle install --with local_development`)\n3. Create your feature branch (`git checkout -b my-new-feature`)\n4. Commit your changes (`git commit -am 'My new feature'`)\n5. Push to the branch (`git push origin my-new-feature`)\n6. Create a new Pull Request\n\n### Testing\nRoo uses Minitest and RSpec. The best of both worlds! Run `bundle exec rake` to\nrun the tests/examples.\n\nYou can run the tests/examples with Rspec like reporters by running\n`USE_REPORTERS=true bundle exec rake`\n\nRoo also has a few tests that take a long time (5+ seconds). To run these, use\n`LONG_RUN=true bundle exec rake`\n\n### Issues\n\nIf you find an issue, please create a gist and refer to it in an issue ([sample gist](https://gist.github.com/stevendaniels/98a05849036e99bb8b3c)). Here are some instructions for creating such a gist.\n\n1. [Create a gist](https://gist.github.com) with code that creates the error.\n2. Clone the gist repo locally, add a stripped down version of the offending spreadsheet to the gist repo, and push the gist's changes master.\n3. Paste the gist url here.\n\n\n## License\n[Roo uses an MIT License](https://github.com/roo-rb/roo/blob/master/LICENSE)\n","funding_links":[],"categories":["Documents \u0026 Reports","Ruby","Spreadsheets","Spreadsheets and Documents"],"sub_categories":["Reports \u0026 Spreadsheets"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froo-rb%2Froo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froo-rb%2Froo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froo-rb%2Froo/lists"}