【问题标题】:To convert Excel into CSV efficiently in ruby在 ruby​​ 中有效地将 Excel 转换为 CSV
【发布时间】:2014-07-09 01:34:11
【问题描述】:

我使用spreadsheet gem 来执行此操作。它可以工作,但有时会很慢。我什至尝试过Roo gem,但这并没有提高性能。有没有更好的方法来完成这项工作?奇怪的是,同一个 excel 中的一些工作表工作得更快,而一些工作表工作得非常慢,甚至长达 1 小时。

我们可以使用开放式办公室在单个 excel 中打开每个工作表(选项卡)并更快地将它们转换为 csv 吗?如果是,我将如何在 ruby​​ 中做到这一点?

或者有更好的解决方案吗?

只是添加一个我用 Roo gem 尝试过的小例子

xls = Roo::Excel.new(source_excel_file)
xls.each_with_pagename do |name, sheet|
  # p sheet.to_csv(File.join(dest_csv_dir,name + ".csv"))
  #sheet.parse(:clean => true)#.to_csv(File.join(dest_csv_dir,name + ".csv"))
  puts name
  puts sheet.parse(:clean => true)
end

【问题讨论】:

标签: ruby-on-rails ruby export-to-csv import-from-excel


【解决方案1】:

懦弱的序言:我是 ruby​​ 的超级新手,对 rails 几乎一无所知,但我之前曾与 Excel 纠缠过。我在本地机器上用 5 张纸创建了一个虚拟工作簿,每张包含 10 列和 1000 行随机生成的数字。我使用以下方法将每张工作表转换为自己的 CSV:

require 'win32ole'
require 'csv'

# configure a workbook, turn off excel alarms
xl = WIN32OLE.new('excel.application')
book = xl.workbooks.open('C:\stack\my_workbook.xlsx')
xl.displayalerts = false

# loop through all worksheets in the excel file
book.worksheets.each do |sheet|
  last_row = sheet.cells.find(what: '*', searchorder: 1, searchdirection: 2).row
  last_col = sheet.cells.find(what: '*', searchorder: 2, searchdirection: 2).column
  export = File.new('C:\\stack\\' + sheet.name + '.csv', 'w+')
  csv_row = []

  # loop through each column in each row and write to CSV
  (1..last_row).each do |xlrow|
    (1..last_col).each do |xlcol|
      csv_row << sheet.cells(xlrow, xlcol).value
    end
    export << CSV.generate_line(csv_row)
    csv_row = []
  end
end

# clean up
book.close(savechanges: 'false')
xl.displayalerts = true
xl.quit

此脚本的眼球基准约为 30 秒,每次尝试都在此之上或之下几秒钟。

【讨论】:

  • 但我认为它适用于 Windows 机器。我想我应该提到它,但我认为它在 mac/unix/linux 中不起作用,对吧?
  • 这个对windows用户来说是一个很好的解决方案,但不幸的是我从不使用windows机器。我使用Mac,我的代码在linux机器上运行。
  • 超级愚蠢的问题,但是在 *nix 上不能获得 win32ole 吗?
  • @DanPantry,不太可能。在幕后,win32ole 就像“使用已安装的 microsoft office 来完成工作”。当您在 Windows+Office 上时,它非常方便(此评论中的所有示例都是从 Office VBA 帮助中直接翻译的);但在任何其他环境中你都无法获得它。
【解决方案2】:

确保您使用的是最新的 Roo (1.13.2)。

还要确保您使用的是跳过尾随空白行的补丁:

https://github.com/Empact/roo/blob/master/lib/roo/worksheet.rb

如果您可以发布一个需要很长时间才能解析的电子表格,它可能会帮助这里的人帮助您。请务必删除所有机密数据。

【讨论】:

  • 是的,我正在使用最新的 gem 。我用 roo gem 试过这个例子,但速度很慢。
  • xls = Roo::Excel.new(source_excel_file) xls.each_with_pagename do |name, sheet| # p sheet.to_csv(File.join(dest_csv_dir,name + ".csv")) #sheet.parse(:clean => true)#.to_csv(File.join(dest_csv_dir,name + ".csv")) puts name puts sheet.parse(:clean => true) end
  • 你能给我一个例子,说明如何在单个 excel 中将 Roo 用于多个工作表。
【解决方案3】:

我假设我们谈论的是旧的 Excel 格式 (xls),似乎电子表格 gem 无论如何都不能与 xlsx 一起使用。

我会尝试使用命令行 spreadhseet 转换器之一:来自 catdoc 包的 xls2csv(非常快,尽管并非所有 Excel 文件都被成功处理)或来自 gnumeric 包的 ssconvert(速度适中,并且需要安装条目GNumeric,有时不是服务器的选项,但非常强大)。

注意:在解析 Excel 时,roo 只需要电子表格并将其封装在自己的 API 中,因此它永远不会比电子表格更快或更可靠。

NB2:如果我没记错的话(以为是很久以前的事了),尝试从 ruby​​ 自动化 OpenOffice 是 a) 非常困难 b) 非常慢。

【讨论】:

  • xls2csv 唯一的问题是如果我在一个 excel 中有多个工作表并希望它们是单独的 CSV。
  • xls2csv 有 -b 选项 - “换页符字符串”。所以,如果你的 xls 被 xls2csv 成功解析(我的不是,所以我无法测试它),你可以使用更多的 bash 魔法分割输出文件,比如here;或者您可以使用 popen 将输出捕获到 Ruby 中,并在其上使用常规的 split 方法。
  • 我的都没有被解析:( .
  • 试试ssconvert,然后(不过,如果在服务器上,它除了安装完整的 gnumeric 之外别无选择,而这又需要所有 gnome 库)
【解决方案4】:
xls_file = Roo::Excelx.new('test.xlsx')
CSV.open('test.csv') do |csv|
    (2..xls_file.last_row).each do |i| # if you do not need header otherwise (1..xls_file.last_row)
        csv << a.row(i)
    end
end

【讨论】:

猜你喜欢
  • 2022-10-21
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-19
  • 2012-10-10
  • 2016-11-30
  • 1970-01-01
相关资源
最近更新 更多