Ruby: cannot parse Excel file exported as CSV in OS X
Try: CSV.open('filename', 'r', ?,, ?\r)
As cantlin notes, for Ruby 2 it's:
CSV.new('file.csv', 'r', :col_sep => ?,, :row_sep => ?\r)
I'm pretty sure these will DTRT for you. You can also "fix" the file itself (in which case keep the old open
) with the following vim
command: :%s/\r/\r/g
Yes, I know that command looks like a total no-op, but it will work.
Exporting Ruby CSV from ActiveRecord single quote in Excel looks weird
I fixed my problem by adding BOM characters in the beginning of my file to force the UTF-8 in Excel.
CSV.open(fileNameInbound, 'wb', encoding: 'UTF-8') do |csv|
myModel.all.each do |m|
csv << ['\xef\xbb\xbf']
csv << m
end
end
Ruby CSV does not understand \r\n as row end
Works for me in 1.9.3:
mark@ubuntu:~$ irb
1.9.3p0 :001 > require 'csv'
=> true
1.9.3p0 :002 > CSV.foreach("rn.csv") do |row|
1.9.3p0 :003 > p row
1.9.3p0 :004 > end
["1","2","3","4","5"]
["6","7","8","9","10"]
And the file does indeed have carriage returns in it:
mark@ubuntu:~$ od -a rn.csv
0000000 1 , 2 , 3 , 4 , 5 cr nl 6 , 7 , 8
0000020 , 9 , 1 0 cr nl
0000027
write.csv() writes a different result from Mac OS than from Windows 10?
The problem isn’t R, the problem is Excel.
Excel has its own ideas about what a platform’s character encoding should be. Notably, it insists, even on modern macOSs, that the platform encoding is naturally Mac Roman. Rather than the actually prevailing UTF-8.
The file is correctly written as UTF-8 on macOS by default.
To get Excel to read it correctly, you need to choose “File” › “Import…”, and from thre follow the import wizard which lets you specify the file encoding.
How to convert CSV to Excel?
According to this post, the spreadsheet gem is a possibility. It looks like this is a very popular gem. Check it out. Example:
book = Spreadsheet::Workbook.new
sheet1 = book.create_worksheet
header_format = Spreadsheet::Format.new(
:weight => :bold,
:horizontal_align => :center,
:bottom => true,
:locked => true
)
sheet1.row(0).default_format = header_format
FasterCSV.open(input_path, 'r') do |csv|
csv.each_with_index do |row, i|
sheet1.row(i).replace(row)
end
end
book.write(output_path)
According to this post, write_xlsx is a possibility.
I've used the Apache POI library with JRuby to export xls files. Here's a quick example.
require 'java'
require 'poi.jar'
# require 'poi-ooxml.jar'
require 'rubygems'
require 'fastercsv'
java_import org.apache.poi.hssf.usermodel.HSSFWorkbook;
wb = HSSFWorkbook.new # OR XSSFWorkbook, for xlsx
sheet = wb.create_sheet('Sheet 1')
FasterCSV.open(ARGV.first) do |csv|
csv.each_with_index do |csv_row, line_no|
row = sheet.createRow(line_no)
csv_row.each_with_index do |csv_value, col_no|
cell = row.createCell(col_no)
cell.setCellValue(csv_value) unless csv_value.nil? # can't pass nil.
end
end
end
f = java.io.FileOutputStream.new("workbook.xls")
wb.write(f)
f.close
Some useful methods for formatting POI spreadsheets are
sheet.createFreezePane(0,1,0,1)
wb.setRepeatingRowsAndColumns(0, -1, -1, 0, 1)
sheet.setColumnWidth(i, 100 *256)
sheet.autoSizeColumn(i)
, but beware, if you're running in headless mode, you have to calljava.lang.System.setProperty("java.awt.headless", "true")
You can also use Win32ole on Windows, if you have Excel installed
require 'win32ole'
require 'rubygems'
require 'fastercsv'
xl = WIN32OLE.new('Excel.Application')
xl.Visible = 0
wb = xl.Workbooks.Add
ws = wb.Worksheets(1)
FasterCSV.open(ARGV.first) do |csv|
csv.each_with_index do |csv_row, line_no|
csv_row.each_with_index do |value, col|
ws.Cells(line_no + 1, col + 1).Value = value
end
end
end
wb.SaveAs("workbook.xls", 56) # 56 = xlExcel8 aka Excel 97-2003. i.e. xls
wb.SaveAs("workbook.xlsx", 51) # 51 = xlOpenXMLWorkbook
wb.SaveAs("workbook.xlsb", 50) # 50 = xlExcel12
wb.Close(2) #xlDoNotSaveChanges
xl.Quit
Some useful methods for formatting with Excel are
xl.Rows(1).Font.Bold = true
ws.Cells.EntireColumn.AutoFit
Yet another option is to write directly to Microsoft's XML Spreadsheet format, as Ryan Bates at Railscasts.com does at the end of his Exporting CSV and Excel episode.
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table>
<Row>
<Cell><Data ss:Type="String">ID</Data></Cell>
<Cell><Data ss:Type="String">Name</Data></Cell>
<Cell><Data ss:Type="String">Release Date</Data></Cell>
<Cell><Data ss:Type="String">Price</Data></Cell>
</Row>
<% @products.each do |product| %>
<Row>
<Cell><Data ss:Type="Number"><%= product.id %></Data></Cell>
<Cell><Data ss:Type="String"><%= product.name %></Data></Cell>
<Cell><Data ss:Type="String"><%= product.released_on %></Data></Cell>
<Cell><Data ss:Type="Number"><%= product.price %></Data></Cell>
</Row>
<% end %>
</Table>
</Worksheet>
</Workbook>
This gem looks promising, too.
CHCSVWriter Unicode Problem
As nobody could resolve my problem,
I found that Unicode encoding is not very well supported with Microsoft Excell ( mac ).
In other hand, because of this fact that I'm using Perisan language for my data entries so I have to use NSUTF16StringEncoding
( why UTF8StringEncoding
didn't work ? I don't know !! ) and when I open the .csv file I have all my data in just one column ( I have 16 column ) and Microsoft Excell can not detect comma (,) as separation delimiter !!!
Anyway, now, I am able to open the UTF16 Encoded CSV file using NeoOffice or OpenOffice that well supported Unicode .csv files without any problem !
So, this all about Microsft not Dave deLong's CHCSVWriter. ( thank you Dave, Again )
this my 5th question that I solved by myself !!!
Thank you all anyway.
Related Topics
Sending a Post Request with Net/Http
How to Do Basic Authentication Over Https in Ruby
Cucumber, Capybara and Selenium - Submitting a Form Without a Button
Errno::Enoent: No Such File or Directory Ruby
Carrierwave: Create the Same, Unique Filename for All Versioned Files
How to Get the Ruby Documentation from the Command Line
How to Test a Ruby Application Which Uses Mechanize
Rails Scope Find with Current User
What Are the Uppercase and Lowercase Rules of Ruby Method Name
Rails Plugin for API Key + Secret Key Signing
Ruby: How to Chain Multiple Method Calls Together with "Send"
How to Dynamically Call Routes Helper in Rails
Ruby, Check If Date Is a Weekend
Installing Ruby 2.0.0 Using Rvm
Using Typeahead from Twitter Bootstrap in a Form (Formtastic)