Adding one more row to existing excel file in ruby - ruby-on-rails

I am trying to simply add one more row to an existing excel file using spreadsheet gem.
test_url = "#{Rails.root}/data/Skipped_Records.xls"
if File.exists?(test_url)
book = Spreadsheet.open(test_url)
else
book = Spreadsheet::Workbook.new
book.create_worksheet
end
sheet = book.worksheet(0)
last_index = sheet.row(-1).idx
sheet.row(last_index + 1).concat [index, error]
book.write "#{Rails.root}/data/Skipped_Records.xls"
In first run the file is getting created fine.
But after second run, while opening the file LibreOffice says
Unknown or unsupported excel file format.
I am trying to migrate excel data into rails application using rake task. While doing it few rows are skipped because of certain errors. I am trying to log these skipped records.
Please help.

Related

In Rails I want to read excel file form Live Path like http://www.carsa.jp/admin/data.xlsx

I wants to read a excel file existing on Live URL of another website.
When I hit that URL in browser file is downloading. While in my rails app it is giving below error
No such file or directory # rb_sysopen - http://www.carsa.jp/admin/data.xlsx (Errno::ENOENT)
My Rails app code is as below
data = Roo::Excelx.new('http://www.carsa.jp/admin/data.xlsx')
header = data.row(1)
puts header
Note: If I download file and place it within my application it is working fine but the requirement is to read it from the third-party website in a scheduled job as per the above script.
data = Roo::Excelx.new('lib/data.xlsx')
header = data.row(1)
puts header
Try using Roo::Spreadsheet.open instead of Roo::Excelx.new. According to the Roo Readme:
Roo::Spreadsheet.open can accept both paths and File instances.
This should do the trick:
Roo::Spreadsheet.open('http://www.carsa.jp/admin/data.xlsx')

How do I parse an Excel file that will give me data exactly as it appears visually?

I'm on Rails 5 (Ruby 2.4). I want to read an .xls doc and I would like to get the data into CSV format, just as it appears in the Excel file. Someone recommended I use Roo, and so I have
book = Roo::Spreadsheet.open(file_location)
sheet = book.sheet(0)
text = sheet.to_csv
arr_of_arrs = CSV.parse(text)
However what is getting returned is not the same as what I see in the spreadsheet. For isntance, a cell in the spreadsheet has
16:45.81
and when I get the CSV data from above, what is returned is
"0.011641319444444444"
How do I parse the Excel doc and get exactly what I see? I don't care if I use Roo to parse or not, just as long as I can get CSV data that is a representation of what I see rather than some weird internal representation. For reference the file type I was parsing givies this when I run "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
You need to save the custom formula in a text format on the .xls side. If your opening the .xls file from the internet this won't work but this will fix your problem if you can manipulate the file. You can do this using the function =TEXT(A2, "mm:ss.0") A2 is just the cell I'm using as an example.
book = ::Roo::Spreadsheet.open(file_location)
puts book.cell('B', 2)
=> '16.45.8'
If manipulating the file is not an option you could just pass a custom converter to CSV.new() and convert the decimal time back to the correct format you need.
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"}
Under the hood roo-xls gem uses the spreadsheet gem to parse the xls file. There was a similar issue to yours logged here, but it doesn't appear that there was any real resolution. Internally xls stores 16:45.81 as a Number and associates some formatting with it. I believe the issue has something to do with the spreadsheet gem not correctly handling the cell format.
I did try messing around with adding a format mm:ss.0 by following this guide but I couldn't get it to work, maybe you'll have more luck.
You can use converters option. It seems looking like this:
arr_of_arrs = CSV.parse(text, {converters: :date_time})
http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/CSV.html
Your problem seems to be with the way you're parsing (reading) the input file.
roo parses only Excel 2007-2013 (.xlsx) files. From you question, you want to parse .xls, which is a different format.
Like the documentation says, use the roo-xls gem instead.

Error invoking PDFTK when modify PDF in Rails 4

I am developing Rails 4 application where have to modify existing PDF file.
User can write some comments and click then comments write in existing PDF as well. For this, i used gem 'pdf-toolkit'
But i got below error:
Error invoking PDFTK
My Code:
my_pdf = PDF::Toolkit.open("Credit_One.pdf")
my_pdf.updated_at = Time.now # ModDate
my_pdf["SomeAttribute"] = "Some value"
my_pdf.save!
Where is wrong any one have a idea.
Thanks

Ole::Storage::FormatError: OLE2 signature is invalid

I want to read an Excel File in my Rails Application.
This is how I open my Excel file and read it.
doc = Spreadsheet.open('./try.xls', "r")
sheet = doc.worksheet 0
sheet.each do |row|
array_rows << row.to_a
end
I have it as a rake task.When I try to Read this file it throws an error.
Ole::Storage::FormatError: OLE2 signature is invalid
What is happening? what should I do?
The .xls file must be saved in EXCEL 2003 format. So
File-->Save As
from All Formats dropdown select the Excel year 2003
This solved my problem
On Mac I had to save it as Excel 97-2004(.xls) to get it to work

Determining File Path in Nitrous?

I am running Ruby on Rails on Nitrous
Rails 4.0.1
Ruby 2.0.0p247
I am trying to use the spreadsheet gem and open a file I added to my file system in Nitrous. But spreadsheet needs a file path to the document and the file paths I've tried always come up as
"No such file or directory"
My path I thought I should use is
~/workspace/excel-documents/reports.xls
But that is not working. How do I determine my file path in Nitrous?
EDIT------------------------------------------------------------------------------
Just figured out how to find the file path. Not sure if this should be added to the spreadsheets gem README or not. But I did the following...
Spreadsheet.client_encoding = 'UTF-8'.
require 'spreadsheet'
book = Spreadsheet.open File.absolute_path("excel-documents/report.csv")
sheet1 = book.worksheet 0
last_value = nil
sheet1.each do |row|
last_value = row[0].present? && row[0]
end
File.abosulte_path(). Got lucky on a stack exchange search and found the info on it.
http://www.ruby-doc.org/core-2.1.1/File.html#M000023
But now I'm trying to figure out an OLE2 signature is invalid message. Does any one know how formatting works for csv files in spreadsheets?

Resources