[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7906":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":16,"starSnapshotCount":16,"syncStatus":17,"lastSyncTime":29,"discoverSource":30},7906,"roo","roo-rb\u002Froo","roo-rb","Roo provides an interface to spreadsheets of several sorts.","",null,"Ruby",2879,503,61,89,0,2,14,1,30.11,"MIT License",false,"master",true,[],"2026-06-12 02:01:46","# Roo\n\n[![Build Status](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002Froo-rb\u002Froo\u002Fruby.yml?style=flat-square)](https:\u002F\u002Ftravis-ci.org\u002Froo-rb\u002Froo) [![Maintainability](https:\u002F\u002Fapi.codeclimate.com\u002Fv1\u002Fbadges\u002Fbe8d7bf34e2aeaf67c62\u002Fmaintainability)](https:\u002F\u002Fcodeclimate.com\u002Fgithub\u002Froo-rb\u002Froo\u002Fmaintainability) [![Coverage Status](https:\u002F\u002Fimg.shields.io\u002Fcoveralls\u002Froo-rb\u002Froo.svg?style=flat-square)](https:\u002F\u002Fcoveralls.io\u002Fr\u002Froo-rb\u002Froo) [![Gem Version](https:\u002F\u002Fimg.shields.io\u002Fgem\u002Fv\u002Froo.svg?style=flat-square)](https:\u002F\u002Frubygems.org\u002Fgems\u002Froo)\n\nRoo implements read access for all common spreadsheet types. It can handle:\n* Excel 2007 - 2013 formats (xlsx, xlsm)\n* LibreOffice \u002F OpenOffice.org formats (ods)\n* CSV\n* Excel 97, Excel 2002 XML, and Excel 2003 XML formats when using the [roo-xls](https:\u002F\u002Fgithub.com\u002Froo-rb\u002Froo-xls) gem (xls, xml)\n* Google spreadsheets with read\u002Fwrite access when using [roo-google](https:\u002F\u002Fgithub.com\u002Froo-rb\u002Froo-google)\n\n## Important note about next major release\n\nThere a plan to make a new major release which will have better support for Ruby 3.x\nPlease leave your comments there - https:\u002F\u002Fgithub.com\u002Froo-rb\u002Froo\u002Fissues\u002F630\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\", \"~> 3.0.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:\u002F\u002Fgithub.com\u002Froo-rb\u002Froo\u002Fblob\u002Fmaster\u002Flib\u002Froo.rb#L17) to use for you.\n```ruby\nrequire 'roo'\n\nfile_name = '.\u002Fnew_prices.xlsx'\nxlsx = Roo::Spreadsheet.open(file_name)\nxlsx.info\n# => 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 = '.\u002Frails_temp_upload'\nxlsx = Roo::Spreadsheet.open(file_name, extension: :xlsx)\nxlsx.info\n# => 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(\".\u002Fnew_prices.xlsx\")\nxlsx.info\n# => Returns basic info about the spreadsheet file\n```\n\n### Working with sheets\n\n```ruby\nods.sheets\n# => ['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# => 1             # the number of the first row\nsheet.last_row\n# => 42            # the number of the last row\nsheet.first_column\n# => 1             # the number of the first column\nsheet.last_column\n# => 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  # => { 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: \u002FUPC|SKU\u002F, qty: \u002FATS*\\sATP\\s*QTY\\z\u002F)\n# => [{:id => 727880013358, :qty => 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: [\u002FUPC*SKU\u002F,\u002FATS*\\sATP\\s*QTY\\z\u002F])\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('.\u002Froo_error.xlsx', {:expand_merged_ranges => 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(\"\u002Fdev\u002Fnull\"))\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(\".\u002Ftest_data\u002Ftest_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# => :numeric_or_formula\n\nxlsx.cell(3, 'C')\n# => 600000383.0\n\nxlsx.excelx_value(row,col)\n# => '600000383'\n\nxlsx.formatted_value(row,col)\n# => '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 \u002F 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# => :percentage\n\nods.comment(1,1, ods.sheets[-1])\n\nods.font(1,1).italic?\n# => 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:\u002F\u002Fgithub.com\u002Froo-rb\u002Froo\u002Fblob\u002Fmaster\u002FCHANGELOG.md) to better understand the changes made since 1.13.x.\n\n\n\n## Contributing\n### Features\n1. Fork it ( https:\u002F\u002Fgithub.com\u002Froo-rb\u002Froo\u002Ffork )\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\u002Fexamples.\n\nYou can run the tests\u002Fexamples 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:\u002F\u002Fgist.github.com\u002Fstevendaniels\u002F98a05849036e99bb8b3c)). Here are some instructions for creating such a gist.\n\n1. [Create a gist](https:\u002F\u002Fgist.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:\u002F\u002Fgithub.com\u002Froo-rb\u002Froo\u002Fblob\u002Fmaster\u002FLICENSE)\n","Roo 是一个用于读取多种格式电子表格的 Ruby 库。它支持常见的电子表格类型，包括 Excel 2007-2013（xlsx, xlsm）、LibreOffice\u002FOpenOffice（ods）、CSV 以及通过额外 gem 支持的 Excel 97-2003 和 Google 表格等。Roo 提供了简单易用的 API 来打开、读取和处理这些不同类型的文件，并且能够自动检测文件类型以选择合适的解析器。此外，Roo 还提供了对工作表、行和列的基本操作功能。这个库非常适合需要在 Ruby 应用程序中处理多种格式电子表格的场景，例如数据导入导出、报表生成等任务。","2026-06-11 03:14:59","top_language"]