我在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"}