将UTF8数据导出到Excel的最佳方法是什么?

时间:2009-01-16 19:30:27

标签: xml excel csv utf-8 utf-16

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

所以我已经做了一些挖掘(Intervals人员有一个有趣的帖子about it here),并且有一些有限的,如果荒谬烦人的选择。其中:

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

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

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

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

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

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

8 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:7)

经过几个小时的同样问题的挣扎后,我发现了关于这个主题的优秀帖子

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

  

所以,这些是三个规则   处理Excel-friendly-CSV:

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

但是,如果你使用ruby,你的问题就解决了: 首先你有FasterCSV宝石

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:1)

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

xml version =“1.0”encoding =“utf-8”

答案 4 :(得分: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程序。

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

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

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

希望这有帮助,

拉​​里

答案 5 :(得分: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) }

答案 6 :(得分:-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);

答案 7 :(得分:-3)

尝试使用OpenOffice Calc - 它更加符合Unicode - 同时使用UTF-8编码导入和导出CSV文件。