如何将CSV转换为Excel?

11

有没有 Ruby 的插件可以将 CSV 文件转换成 Excel 文件?我在 Google 上搜索了一下,但是所有的结果都是将 Excel 文件转换成 CSV。我知道一些 Gem 工具可以稍加修改并用于将 Excel 转换成 CSV,但我需要知道是否有人以前做过这样的转换。


3
通常情况下我们只需让Excel导入CSV文件,通常它会正常工作。 - Ignacio Vazquez-Abrams
另一个几乎本地的选择:XML导入也可以生成“漂亮”的Excel文档。我将Rails的#to_xml输出输入到XSLT中来完成这个过程。 - Martin Carpenter
可能是重复问题:http://stackoverflow.com/questions/6646430/whats-the-easiest-way-to-export-a-csv-to-excel-with-ruby - Mr. Black
1
为什么不直接使用OLE呢?Excel可以直接打开CSV文件并将其保存为XLSX文件... - SwiftMango
1
Excel经常会破坏CSV数据。它会删除前导零,将小写的true/false转换为大写,将大数字转换为科学计数法,还可能有更多的问题。通过发送用户一个XLS文件,您可以控制格式并避免数据丢失。 - John Douthat
3
Excel OLE自动化仅限于Windows系统,而大多数人使用的是Mac或Linux上的Ruby。此外,它还需要付费许可证,而其他选项则是免费的。使用OLE启动还存在问题,例如如果您需要重新激活Office,在使用OLE启动时Excel会无限挂起,需要手动干预才能使其正常工作。 - John Douthat
4个回答

11
根据这篇文章spreadsheet gem可能是一个选择。看起来这是一个非常受欢迎的gem。查看一下。示例:
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)

根据这篇文章write_xlsx 是一种可能性。
我使用Apache POI库和JRuby导出xls文件。这是一个快速的例子。
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

一些有用的格式化POI电子表格的方法:

  • sheet.createFreezePane(0,1,0,1)
  • wb.setRepeatingRowsAndColumns(0, -1, -1, 0, 1)
  • sheet.setColumnWidth(i, 100 *256)
  • sheet.autoSizeColumn(i),但要注意,如果你在无头模式下运行,你需要调用java.lang.System.setProperty("java.awt.headless", "true")

如果你在Windows系统上安装了Excel,你还可以使用Win32ole。

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

格式化Excel的一些有用方法包括:

  • xl.Rows(1).Font.Bold = true
  • ws.Cells.EntireColumn.AutoFit

另一种选项是直接编写到Microsoft的 XML Spreadsheet 格式中,正如Railscasts.com上的Ryan Bates在其Exporting CSV and Excel一集中所做的

<?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>

这个宝石看起来也很有前途


2
似乎如果您已经在使用win32ole,那么您可以直接在Excel中“打开”CSV文件并将其另存为XLS。不过我不确定代码是什么。 - pguardiario
好主意。我原本希望让示例看起来与上面的示例类似,但是直接将CSV文件打开到Excel中是更聪明的想法。 - John Douthat
我发现了另一个宝石,writeexcel 很容易完成工作... 再次感谢。 - Bhushan Lodha

2
如果您找不到将CSV转换为EXCEL的宝石,则可以尝试分别查找两个宝石:
1. 读/写CSV(用于读取CSV文件)例如 FasterCSV 2. 读/写EXCEL(用于写入EXCEL文件)例如 SpreadSheet

3
注意,FasterCSV现在已经作为标准库中的require "csv"内置于Ruby 1.9中。 - Phrogz

2

对于当前看到这篇文章的读者,这些八年来语法有所改变。以下是基于先前答案的代码(为了方便复制粘贴已经重新复制在下面),对我而言完美运行:

def convert_csv_to_xlsx
  book = Spreadsheet::Workbook.new
  sheet1 = book.create_worksheet

  header_format = Spreadsheet::Format.new(
    weight: :bold,
    horizontal_align: :center,
    bottom: :medium,
    locked: true
  )

  sheet1.row(0).default_format = header_format

  CSV.open(input_path, 'r') do |csv|
    csv.each_with_index do |row, i|
      sheet1.row(i).replace(row)
    end
  end

  book.write(output_path)
end

I.E.: FasterCSV现在只是CSV,:bottom已经弃用


-2

简单的方法是:

  1. 使用您喜欢的文本编辑器(如Sublime Text或Notepad)打开CSV文件
  2. 将所有的,(逗号)替换为制表符\t
  3. 将文件另存为.xls扩展名
  4. 使用Excel打开文件,TADA!您已经完成了!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接