Ruby:如何生成具有Excel友好编码的CSV文件

Chr*_*sen 9 ruby csv excel encoding export-to-csv

我生成的CSV文件一旦生成就需要在Excel中打开和查看.Excel似乎需要与UTF-8不同的编码.

这是我的配置和生成代码:

csv_config = {col_sep: ";", 
              row_sep: "\n", 
              encoding: Encoding::UTF_8
             }

csv_string = CSV.generate(csv_config) do |csv|
  csv << ["Text a", "Text b", "Text æ", "Text ø", "Text å"]
end
Run Code Online (Sandbox Code Playgroud)

在Excel中打开时,特殊字符未正确显示:

Text a  Text b  Text æ Text ø Text å
Run Code Online (Sandbox Code Playgroud)

知道如何确保正确编码吗?

Gre*_*ley 12

来自@joaofraga的最高投票答案为我工作,但我找到了另一种解决方案,它也起作用 - 不需要UTF-8到ISO-8859-1转码.

从我读过的,Excel,确实可以处理UTF-8,但由于某种原因,它默认不识别它.但是,如果您将BOM添加到CSV数据的开头,这似乎会导致Excel意识到该文件是UTF-8.

所以,如果您有这样的CSV:

csv_string = CSV.generate(csv_config) do |csv|
  csv << ["Text a", "Text b", "Text æ", "Text ø", "Text å"]
end
Run Code Online (Sandbox Code Playgroud)

只需添加一个BOM字节,如下所示:

"\uFEFF" + csv_string
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我的控制器将CSV作为文件发送,所以这就是我的控制器的样子:

def show
  respond_to do |format|
    format.csv do
      #  add BOM to force Excel to realise this file is encoded in UTF-8, so it respects special characters
      send_data "\uFEFF" + csv_string, type: :csv, filename: "csv.csv"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我应该注意到UTF-8本身根本不需要或推荐BOM,但正如我所提到的,在这种情况下添加它似乎促使Excel意识到该文件确实是UTF-8.


joa*_*aga 9

您应该将编码切换ISO-8859-1为如下:

CSV.generate(encoding: 'ISO-8859-1') { |csv|  csv << ["Text á", "Text é", "Text æ"] }
Run Code Online (Sandbox Code Playgroud)

对于您的上下文,您可以这样做:

config = {
  col_sep: ';',
  row_sep: ';',
  encoding: 'ISO-8859-1'
}

CSV.generate(config) { |csv|  csv << ["Text á", "Text é", "Text æ"] }
Run Code Online (Sandbox Code Playgroud)

我有同样的问题,编码修复.


cuz*_*zic 8

如果有BOM,Excel会理解UTF-8 CSV.这可以这样做:

使用CSV.generate

# the argument of CSV.generate is default string
csv_string = CSV.generate("\uFEFF") do |csv|
  csv << ["Text a", "Text b", "Text æ", "Text ø", "Text å"]
end
Run Code Online (Sandbox Code Playgroud)

使用CSV.open

filename = "/tmp/example.csv"

# Default output encoding is UTF-8
CSV.open(filename, "w") do |csv|
  csv.to_io.write "\uFEFF" # use CSV#to_io to write BOM directly 
  csv << ["Text a", "Text b", "Text æ", "Text ø", "Text å"]
end
Run Code Online (Sandbox Code Playgroud)

  • 感谢 CSV.open 解决方案非常适合我!比其他答案稍微干净的解决方案。 (3认同)
  • 仅供参考:“\uFEFF”是 UTF-16 的 BOM。使用 `\xEF\xBB\xBF` 表示 UTF-8。这是 UTF 编码的 [BOM 列表](https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding)。 (2认同)