将UTF8数据导出到Excel的最佳方式是什么?
所以我们有这个Web应用程序,我们支持UTF8数据。 Hooray UTF8。而且我们可以将用户提供的数据导出为CSV,这一点没有问题 - 在这一点上它仍然是UTF8。问题是,当你在Excel中打开一个典型的UTF8 CSV文件时,它将其读取为ANSII编码的文本,并相应地尝试读取ø和ü这样的两个字节的字符作为两个独立的字符,并最终导致失败。将UTF8数据导出到Excel的最佳方式是什么?
所以我做了一些挖掘(间隔人员有一个有趣的职位about it here),并有一些有限的,如果可笑的恼人的选择那里。其中:
- 提供一个UTF-16小端TSV文件,Excel将正确解释,但不支持多行数据
- 在HTML表格中使用Excel MIME类型提供的数据或文件扩展名(不确定此选项是否支持UTF8)
- 有几种方法可以将XML数据导入到各种最新版本的Excel中,理论上这些将支持UTF8。 SpreadsheetML,使用自定义XSLT或通过模板生成新的Excel XML格式。
看起来无论如何,我可能会继续为那些不使用Excel的人提供一个普通的CSV文件,并为Excel单独下载选项。
什么是生成Just-For-Excel文件的最简单方法,它将正确支持UTF8,我亲爱的Stack Overflowers?如果这个最简单的选项只支持最新版本的Excel,那还是很有趣的。
我正在Rails堆栈上做这件事,但好奇的是.Net-ers和任何框架上的人如何处理这个问题。我自己在几个不同的环境中工作,这绝对是一个将再次成为问题的问题。
更新2010-10-22:我们在我们的时间跟踪系统Tempo中使用了Ruport gem,以便在我首次发布此问题时提供CSV导出。我的一个同事,埃里克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
你忘记创建OleDB数据源和Excel Interop,但也存在这些问题。
我推荐SpreadsheetML选项。它工作得很好,很可能你的平台有一些体面的工具来构建xml文件,并且早在OfficeXP中就已经完全支持它。 Office2000不受支持,但个人经验是它以有限的方式工作。
我有将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插件,效果很好。
希望这有助于
拉里
尝试OpenOffice的计算器 - 它更Unicode的友好 - 无论是导入和导出CSV文件使用UTF-8编码。
同样的问题挣扎了几个小时后,我发现关于这个问题的这个优秀的帖子
http://blog.plataformatec.com.br/2009/09/exporting-data-to-csv-and-excel-in-your-rails-app/ 报价:
所以,这些都是 的三个规则处理与Excel友好-CSV:
- 使用表格,而不是逗号。
- 字段不能包含换行符。
- 使用UTF-16 Little Endian将文件发送给用户。并手动添加 Little Endian BOM。
不过,如果你使用的红宝石,你的问题就解决了: 首先,你必须在FasterCSV宝石
但我结束了使用电子表格的宝石直接生成EXCELL表格 (我有链接限制,只是谷歌电子表格+ rubyforge) 辉煌!
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);
我发现,如果你设置的网页的字符集编码为UTF-8,然后响应。Binary在csv文件的顶部写入UTF-8字节顺序标记(0xEF 0xBB 0xBF),然后Excel 2007(不确定其他版本)会将其识别为utf-8并将其正确打开。
我倒在这篇文章寻找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) }
“你忘了......一个OLEDB ......” 嘘!这是一个unix环境,所以我想避免那种Voodoo。谢谢你的提示! – 2009-01-16 19:49:06
那为什么它被标记为正确? – hoju 2012-04-03 13:53:37
@理查德 - 因为第二段,它不依赖oledb。虽然从1年半后发布的更新中,应该有一个答案,在这里指向人们Ruby Rubpert。 – 2012-04-03 13:54:59