[译] Ruby如何访问Excel文件
Parsing Excel Files with Ruby
本文中,我将会评判几种Ruby语言访问Excel文件的库。我将要讨论针对不同格式的Excel文件访问的现有的几个Ruby库。本文中更多地聚焦于读取Excel文件,但是也对与更改/写入Excel文件稍作了些讨论。
如果你迫不及待地想要查看代码,请移步我提交与Github上的 一个项目 ,项目中有一些读取Excel文件的代码片段,都是本文所提到的。
Excel文件类型
Before we get into the different Ruby libraries, let’s talk about Excel files. It is important to identify the type of Excel files that you are going to be using. There are two main types: legacy files and the newer OOXML file format introduced in Microsoft Office 2007.
There is a nice description of the differences on Wikipedia. The tldr; version is that the legacy file format includes files with the following extensions:
文件扩展名 | 说明 |
---|---|
.xls | 传统格式的Excel文件 |
.xlt | 传统格式的Excel模板 |
.xlm | 带有宏代码的传统格式的Excel文件 |
Microsoft Excel 2007 abandoned the legacy binary format and switched to the Open Office XML (OOXML) format that is used today. These files use the following extensions:
文件扩展名 | 说明 |
---|---|
.xlsx | OOXML Excel file |
.xlst | OOXML Excel file template |
.xlsm | OOXML Excel file with macros |
确定你将要涉及何种格式的Excel文件(传统格式 或 OOOXML格式)非常的重要。如果你使用Excel软件工作,可能会经常地在各种格式之间转来转去,但是在我的场景中,是从外部收到Excel文件且不能掌控文件格式,但是我也不想依靠手工进行格式转换。而且也没有必要,现代的.xlsx格式一般都可以使用其他的电子表格软件访问,例如: Numbers 和 LibreOffice。
Ruby下的Excel 库
有很多Ruby库用来访问Excel——可能太多了。当我研究这些不同的库时,着实耗费了不少时间来搞清楚它们的功能和限制。我发现下面这些问题对于调研一个库来说非常有用:
- 支持何种格式的Excel文件?
- 支持读取还是写入,亦或读写都支持?
- 能否支持巨大的文件?速度够快吗?
- 是否必须读取文件?能否支持流模式?
根据应用的不同,这些问题中的几个或全部可能非常重要。
选择合适的库
下面的表详细列出了六个不同的Ruby Excel访问库的功能特点:
库 | 许可证 | 支持.xlsx | 支持.xls | 能力 |
---|---|---|---|---|
axlsx | MIT | yes | no | write |
rubyXL | MIT | yes | no | read/write |
roo | MIT | yes | yes | read |
creek | MIT | yes | no | read |
spreadsheet | GPLv3 | no | yes | read/write |
simple_xlsx_reader | MIT | yes | no | read |
基于你的需求,这其中的一个或多个库可能能帮上忙。考虑如下使用场景:
写入 .xlsx 文件
如果你需要写入 .xlsx文件,
axslx是一个不错的选择。它支持写单元格数值生成统计图表。如果你需要一个轻量级的库,rubyXL 是个不错的选项。
读取 .xlsx 文件
如果你只是需要读取 .xlsx
文件,你可以在rubyXL、roo、creek和simple_xlsx_reader之中选择一个。roo是个非常普遍的选择,因为它还支持传统的.xls格式。然而,如果你关注速度,
creek和simple_xlsx_reader显然更善于处理大文件。如果你想要从IO
数据流(而不是文件)中读取数据,rubyXL 就成了唯一的选择了。
读取和写入 .xlsx 文件
如果你需要读取并写入.xlsx
文件,你有两个选项。你可以使用 rubyXL,它支持读取和写入。另一个选项就是,你可以使用两个不同的库,一个用于读取,一个用于写入。
读取和写入传统Excel文件
要想支持传统的.xls
格式会有更多的约束。如果你仅仅需要支持传统 .xls,我推荐
spreadsheet,它支持读取和写入。如果你同时需要支持.xlsx格式,我更推荐选择第二个gem来做此事......除非你仅仅需要读取功能,这样的话
你可以选择 roo ,它既支持读取传统格式也支持现代格式。
好消息是,无论最终你选择了那种库,打开文件并读取的代码还是很简单的,并且使用不同库看上去非常地相似。例如,下面是使用creek的代码。
require 'creek' workbook = Creek::Book.new 'path/to/file.xlsx' worksheets = workbook.sheets worksheets.each do |worksheet| worksheet.rows.each do |row| row_cells = row.values # do something with row_cells end end
我提交到GitHub上的项目中,有使用每种库读取.xlsx 的示例代码。
性能
如果需要读取巨大数据量的Excel文件,你可能相应比较各种库的性能。我建立了一个快速地有些脏代码的性能测试程序,测试了上面表格中的4种能够读取 .xlsx格式的库
。
我创建了示例.xlsx文件,分别含有
500、10000、50000、200000和500000行数据。然后,我运行了代码来读取每个文件(即读取文件中每一行数据)。使用各种库读取每个示例文件的代码可以再这里 获得。
我每种库读取各个文件都跑了3遍,记录了平均时间(每一遍时间变化都不是很大)。
rubyXL 和 roo性能大体相当, 读取500000行的Excel文件需要2分多钟。 creek 和simple_xlsx_reader 则都快的多了,只需要不足一分钟就能读取 500000行的Excel文件。
我希望本文能为你使用Ruby语言访问Excel文件提供些许地指引。如果你正在使用一种我没有提到的库,并且你很喜欢它,请务必告知我。