7

我在 Rails 5 (Ruby 2.4) 上。我想阅读一个 .xls 文档,并且我想将数据转换为 CSV 格式,就像它出现在 Excel 文件中一样。有人推荐我使用 Roo,所以我有

book = Roo::Spreadsheet.open(file_location)
sheet = book.sheet(0)
text = sheet.to_csv
arr_of_arrs = CSV.parse(text)

但是,返回的内容与我在电子表格中看到的不同。例如,电子表格中的一个单元格有

16:45.81

当我从上面获取 CSV 数据时,返回的是

"0.011641319444444444"

如何解析 Excel 文档并准确获取我所看到的内容?我不在乎我是否使用 Roo 来解析,只要我能得到 CSV 数据,它代表我所看到的,而不是一些奇怪的内部表示。作为参考,当我运行“file name_of_file.xls”时,我正在解析的文件类型给出了这个......

Composite Document File V2 Document, Little Endian, Os: Windows, Version 5.1, Code page: 1252, Author: Dwight Schroot, Last Saved By: Dwight Schroot, Name of Creating Application: Microsoft Excel, Create Time/Date: Tue Sep 21 17:05:21 2010, Last Saved Time/Date: Wed Oct 13 16:52:14 2010, Security: 0
4

4 回答 4

3

您需要将自定义公式以文本格式保存在 .xls 端。如果您从 Internet 打开 .xls 文件,这将不起作用,但如果您可以操作该文件,这将解决您的问题。您可以使用函数=TEXT(A2, "mm:ss.0")A2 来执行此操作,这只是我作为示例使用的单元格。

在此处输入图像描述

book = ::Roo::Spreadsheet.open(file_location)
puts book.cell('B', 2) 
=> '16.45.8' 

如果操作文件不是一个选项,您可以将自定义转换器传递给CSV.new()并将十进制时间转换回您需要的正确格式。

require 'roo-xls'
require 'csv'

CSV::Converters[:time_parser] = lambda do |field, info| 
  case info[:header].strip
  when "time" then  begin 
                      # 0.011641319444444444 * 24 hours * 3600 seconds = 1005.81 
                      parse_time =  field.to_f * 24 * 3600
                      # 1005.81.divmod(60) = [16, 45.809999999999999945]
                      mm, ss = parse_time.divmod(60)
                      # returns "16:45.81"
                      time = "#{mm}:#{ss.round(2)}"  
                      time 
                    rescue
                      field 
                    end
  else 
    field  
  end
end

book = ::Roo::Spreadsheet.open(file_location)
sheet = book.sheet(0)
csv = CSV.new(sheet.to_csv, headers: true, converters: [:time_parser]).map {|row| row.to_hash}
puts csv 
=> {"time "=>"16:45.81"}
   {"time "=>"12:46.0"}
于 2017-04-05T02:25:35.943 回答
1

在引擎盖下roo-xls gem使用电子表格 gem来解析 xls 文件。与您在此处记录的问题类似,但似乎没有任何真正的解决方案。在内部 xls 存储16:45.81为数字并将一些格式与它相关联。我相信这个问题与电子表格 gem 没有正确处理单元格格式有关。

我确实尝试mm:ss.0按照本指南添加格式,但我无法让它工作,也许你会有更多的运气。

于 2017-04-02T00:57:53.467 回答
0

您的问题似乎与您解析(读取)输入文件的方式有关。

roo仅解析 Excel 2007-2013 ( .xlsx) 文件。根据您的问题,您想解析 .xls,这是一种不同的格式。

就像文档说的那样,请改用roo-xlsgem。

于 2017-04-01T19:14:29.590 回答
0

您可以使用转换器选项。看起来像这样:

arr_of_arrs = CSV.parse(text, {converters: :date_time})

http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/CSV.html

于 2017-03-28T21:01:23.780 回答