28

所以我们有这个支持 UTF8 数据的网络应用程序。万岁UTF8。我们可以将用户提供的数据导出到 CSV 中,这没有问题——那时它仍然是 UTF8。问题是,当您在 Excel 中打开一个典型的 UTF8 CSV 时,它会将其读取为 ANSII 编码的文本,并因此尝试将 ø 和 ü 等两字节字符作为两个单独的字符读取,而您最终会失败。

所以我做了一些挖掘(Intervals 的人在这里有一篇关于它的有趣帖子),并且有一些有限的,如果可笑的烦人的选项。其中:

  • 提供 Excel 将正确解释但不支持多行数据的 UTF-16 Little Endian TSV 文件
  • 提供具有 Excel mime 类型或文件扩展名的 HTML 表中的数据(不确定此选项是否支持 UTF8)
  • 有大约三到四种方法可以将 XML 数据导入到各种最新版本的 excel 中,理论上这些方法都支持 UTF8。SpreadsheetML,使用自定义 XSLT,或通过模板生成新的 Excel XML 格式。

看起来无论如何,我可能会继续为那些不使用 Excel 的人提供一个普通的旧 CSV 文件,并为 Excel 提供一个单独的下载选项。

亲爱的 Stack Overflowers,生成正确支持 UTF8 的 Just-For-Excel 文件的最简单方法是什么?如果这个最简单的选项只支持最新版本的 Excel,那仍然很有趣。

我在 Rails 堆栈上执行此操作,但很好奇 .Net-ers 和任何框架上的人员如何处理此问题。我自己在几个不同的环境中工作,这绝对是一个会再次出现的问题。

2010-10-22 更新:当我第一次发布这个问题时,我们一直在我们的时间跟踪系统Tempo中使用 Ruport gem来提供 CSV 导出。我的一位同事 Erik Hollensbee 为 Ruport 提供了一个快速过滤器,为我们提供了实际的 Excel XSL 输出,我想我会在这里与任何其他 ruby​​ 专家分享:

require 'rubygems'
require 'ruport'
require 'spreadsheet'
require 'stringio'

Spreadsheet.client_encoding = "UTF-8"

include Ruport::Data

class Ruport::Formatter::Excel < Ruport::Formatter
  renders :excel, :for => Ruport::Controller::Table

  def output
    retval = StringIO.new

    if options.workbook
      book = options.workbook
    else
      book = Spreadsheet::Workbook.new
    end

    if options.worksheet_name
      book_args = { :name => options.worksheet_name }
    else
      book_args = { }
    end

    sheet = book.create_worksheet(book_args)

    offset = 0

    if options.show_table_headers
      sheet.row(0).default_format = Spreadsheet::Format.new(
        options.format_options || 
        { 
          :color => :blue,
          :weight => :bold,
          :size => 18
        }
      )
      sheet.row(0).replace data.column_names
      offset = 1
    end

    data.data.each_with_index do |row, i|
      sheet.row(i+offset).replace row.attributes.map { |x| row.data[x] }
    end

    book.write retval
    retval.seek(0)
    return retval.read
  end
end
4

8 回答 8

9

我发现如果你把网页的charset编码设置为utf-8,然后Response.Binary在csv文件的顶部写入UTF-8字节顺序标记(0xEF 0xBB 0xBF),然后是Excel 2007(不确定其他版本)将其识别为 utf-8 并正确打开它。

于 2010-07-21T15:16:10.627 回答
7

在同一个问题上挣扎了几个小时后,我发现了这篇关于这个主题的优秀帖子

http://blog.plataformatec.com.br/2009/09/exporting-data-to-csv-and-excel-in-your-rails-app/ 报价:

因此,以下是处理 Excel-friendly-CSV 的三个规则:

  1. 使用表格,而不是逗号。
  2. 字段不得包含换行符。
  3. 使用 UTF-16 Little Endian 将文件发送给用户。并手动包含一个 Little Endian BOM。

但是,如果您使用的是 ruby​​,您的问题就解决了:首先您拥有FasterCSV gem

但我最终使用了直接生成 Excel 电子表格的电子表格 gem(我有链接限制,只是 google 电子表格 + ruby​​forge)太棒了!

于 2010-01-19T05:41:02.967 回答
5

您忘记了创建 OleDB 数据源和 Excel 互操作,但这些也存在问题。

我推荐SpreadsheetML选项。它工作得很好,很可能你的平台有一些不错的工具来构建 xml 文件,并且早在 OfficeXP 就完全支持它。不支持Office2000,但个人经验是它的工作方式有限。

于 2009-01-16T19:41:15.123 回答
1

如果您使用 utf 编码创建 XML 并将其保存为 .xls,它甚至会打开那些两字节字符:

xml 版本="1.0" 编码="utf-8"

于 2009-01-16T19:51:00.067 回答
1

我在将 UTF8 数据发送到 Excel 时遇到了完全相同的问题。我的解决方案:

当前版本的 Perl Spreadsheet::WriteExcel cpan 代码正确地使用 UTF8 数据写入 Excel 文件。

所以我写了一个 Rails 插件,它 a) 打开一个双向管道到 perl 程序 b) 将数据,一次一行,发送到 perl 程序。我使用 Yaml 作为消息数据格式。(标准 Ruby yaml 不是 UTF8,有一个特殊版本可用,ya2yaml) c) perl 程序创建 excel 文件 d) 当 Rails 程序指示(通过 yaml 消息)最后一行已发送时,perl 程序创建excel 文件并将状态发送回 rails 程序。

当然,通过并行进程和管道将 perl 程序添加到 rails 项目在很大程度上属于“工程”范畴,而不是“计算机科学”范畴。(它完成了工作,但并不优雅。)但它确实运行良好,并为我节省了将 WriteExcel 代码移植到 Ruby 所需的数周时间。另请注意,WriteExcel 当前可用的 Ruby 端口不处理 utf8。

我的 sw 是允许的开源软件,但我还没有开始发布它。如果您希望它处于当前状态,请参阅http://sandbox.kluger.com/write_excel_v.5.tar

请注意,您需要在后台进程中创建您的 excel 文件,而不是在 Rails 控制器的进程中,因为这会在您制作 excel 文件时阻止其他浏览器客户端。我使用 DelayedJob 插件,效果很好。

希望这可以帮助,

拉里

于 2009-03-06T22:08:02.337 回答
1

我在这篇文章中寻找 Ruby 的答案,为什么 Excel 不能正确加载带有 utf-8 字符的 CSV。在四处搜索和试验后,这个解决方案对我有用:

csv_content = CSV.generate(col_sep: "\t", headers: :first_row, encoding: 'utf-8') do |csv|
  csv << ["header1", "header2"]
  csv << ["content1", "content2"]
end
write_content = Iconv.conv("utf-16le", "utf-8", "\xEF\xBB\xBF")
write_content += Iconv.conv("utf-16le", "utf-8", csv_content)
File.open("listing.csv", 'wb') {|f| f.write(write_content) }
于 2011-11-15T05:06:56.617 回答
-1

Excel 无法正确处理 UTF-8。您应该改用满足您需求的代码页

Response.ContentType = "text/plain";
// codepage: 28591, codepage name:iso-8859-1, codepage display name: Western European (ISO)
Response.ContentEncoding = System.Text.Encoding.GetEncoding(28591);
于 2010-03-05T09:21:59.267 回答
-3

试试 OpenOffice Calc - 它对 Unicode 更友好 - 使用 UTF-8 编码导入和导出 CSV 文件。

于 2009-05-25T22:22:05.617 回答