Parsing Excel Files with Ruby

 BY: MATT NEDRICH   翻译:佣工7001

本文中,我将会评判几种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——可能太多了。当我研究这些不同的库时,着实耗费了不少时间来搞清楚它们的功能和限制。我发现下面这些问题对于调研一个库来说非常有用:

  1. 支持何种格式的Excel文件?
  2. 支持读取还是写入,亦或读写都支持?
  3. 能否支持巨大的文件?速度够快吗?
  4. 是否必须读取文件?能否支持流模式?

根据应用的不同,这些问题中的几个或全部可能非常重要。

选择合适的库

下面的表详细列出了六个不同的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文件提供些许地指引。如果你正在使用一种我没有提到的库,并且你很喜欢它,请务必告知我。

[译] Ruby如何访问Excel文件的更多相关文章

  1. 020. asp.net访问Excel文件

    <asp:GridView ID="GridView1" runat="server" BackColor="#DEBA84" Bor ...

  2. odi 12.2.1中访问excel文件

    由于在odi 12.2.1中,必须使用jdk1.8,而jdk1.8中jdbc-odbc bridge已经不再支持,因此,可以使用Progress DataDirect SequeLink来充当jdbc ...

  3. .Net读取Excel文件时丢失数据的问题 (转载)

    相信很多人都试过通过OleDB读取Excel文件,这种方法效率十分高,只是有一点会让人十分头痛,就是当一列中既有混合型数据,又有纯数据时,往往容易丢失数据. 百度过后,改连接字符串 “HDR=YES; ...

  4. Spring Boot下的一种导入Excel文件的代码框架

    1.前言 ​ Spring Boot下如果只是导入一个简单的Excel文件,是容易的.网上类似的文章不少,有的针对具体的实体类,代码可重用性不高:有的利用反射机制或自定义注解,开发了Excel导入工具 ...

  5. 通过数据库方式访问excel 2007及其以后(xlsx)文件的连接字符串

    sqlconn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\test3.xls;Extended Properties=&q ...

  6. [译]使用Pandas读取大型Excel文件

    上周我参加了dataisbeautiful subreddit上的Dataviz Battle,我们不得不从TSA声明数据集创建可视化.我喜欢这种比赛,因为大多数时候你最终都会学习很多有用的东西. 这 ...

  7. SQL SERVER导入EXCEL文件:无法创建链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.Ace.OLEDB.12.0" 的实例。

    [方法一] --开启导入功能    exec sp_configure 'show advanced options',1    reconfigure    exec sp_configure 'A ...

  8. C#操作Excel文件

    .Net平台上对Excel进行操作主要有两种方式.第一种,把Excel文件看成一个数据库,通过OleDb的方式进行读取与操作:第二种,调用Excel的COM组件.两种方式各有特点. 注意一些简单的问题 ...

  9. C#中实现excel文件批量导入access数据表中

    一 .界面简单设计如下: 二 .代码如下: using System; using System.Collections.Generic; using System.ComponentModel; u ...

随机推荐

  1. bootstrap的selectpicker的方法

    方法 .selectpicker('val') 您可以通过调用val元素上的方法来设置所选值. 1 2 $('.selectpicker').selectpicker('val', 'Mustard' ...

  2. 开始Golang之旅了

  3. ESA2GJK1DH1K基础篇: 阿里云物联网平台: 测试云平台显示MQTT客户端发过来的消息

    现在这里空空如也 咱自定义的也没有数据 现在就是传上来温度数据,让这里显示温度数据 你发布的主题  /sys/a1m7er1nJbQ/Mqtt/thing/event/property/post 发布 ...

  4. axios二次封装

    import axios from "axios" //请求拦截器 axios.interceptors.request.use(function (config) { retur ...

  5. 用js写个原生的ajax过程

    var xhr=new XMLHttpRequset(); xhr.addEventListener("load",loadHandler); xhr.open("GET ...

  6. priority_queue(优先队列)使用方法

    priority_queue默认是一个大根堆: 并且出队方式与普通队列queue的front不一样,是top . 如果想用小根堆,可以修改定义时的参数: priority_queue<int,v ...

  7. sparksql基础知识二

    目标 掌握sparksql操作jdbc数据源 掌握sparksql保存数据操作 掌握sparksql整合hive 要点 1. jdbc数据源 spark sql可以通过 JDBC 从关系型数据库中读取 ...

  8. js中的new操作符解析

    new 操作符做了以下事情: 1.创建一个对象,将对象赋值给this function Person(name, age) { console.log(this) //Person {} } let ...

  9. 内置函数、反射、__str__、__del__、元类

    一.内置函数的补充 isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo: pass obj=Foo() print(isinstance(obj,Foo) ...

  10. eclipse中自动生成serialVersionUID

     serialVersionUID作用:  序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性.       如果你修改代码重新部署后出现序列化错误,可以考虑给相应的类增加seri ...