我在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)
但是返回的内容与我在电子表格中看到的不同.对于isntance,电子表格中的单元格具有
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
解决方法
您需要在.xls端以文本格式保存自定义公式.如果您从互联网上打开.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"}