sep =“;”语句会破坏由XSL生成的CSV文件中的utf8 BOM

我目前正在用XSLT开发CSV导出。 在我的情况下,CSV文件将使用%99%的Excel,所以我必须考虑Excel的行为。

我的第一个问题是csv中的德文特殊字符。 即使CSV编码是UTF8,Excel也无法用UTF8正确打开CSV文件。 特殊字符越来越奇怪的符号。 我find了这个问题的解决scheme。 我刚刚添加了3个额外的字节( EF BB BF – 又名BOM标头 )开头的内容字节。 因为UTF8 BOM就是这样说的,嘿,伙计,这是UTF8,正确地打开它到Excel。 问题解决了!

而我的第二个问题是关于分隔符。 默认的分隔符可以是逗号或分号取决于地区。 我认为这是德国的分号和英国的逗号。 所以,为了防止这个问题,我不得不添加下面的行:

<xsl:text>sep=;</xsl:text> 

要么

 <xsl:text>sep=,</xsl:text> 

(这个分隔符不是硬编码的)

但我找不到任何解决scheme的问题是,如果您添加“sep =;” 或者在使用UT8-BOM生成CSV文件时,文件的开头是“sep =”,但是BOM无法正确显示特殊字符! 而且我确定BOM字节总是在字节数组的开头。 该屏幕截图来自Mac OS X中的MS Excel:

在这里输入图像描述

前3个符号属于BOM标题。

你有没有像这个问题,或者你有什么build议吗? 谢谢。

编辑:

我分享打印屏幕。

一个。 使用BOM和 <xsl:text>sep=;</xsl:text>

在这里输入图像说明

只需与BOM

在这里输入图像说明

Java代码:

 // Write the bytes ServletOutputStream out = resp.getOutputStream(); if(contentType.toString().equals("CSV")) { // The additional bytes in below is prefix indicates that the content is in UTF-8. out.write(239); out.write(187); out.write(191); } out.write(bytes); // Content bytes, in this case XSL 

XSL代码:

 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes" /> <xsl:template match="/"> <xsl:text>sep=;</xsl:text> <table> ... </table> </xsl:template> 

你是对的,当有人双击一个CSV文件时,在Excel 2007中没有办法让它在不同的语言环境中正确加载编码和分隔符。

这似乎是当你指定sep = BOM后忘记了BOM已经告诉它,它是UTF-8。

您必须指定BOM,因为在某些语言环境中,Excel不检测分隔符。 比如在丹麦,默认的分隔符是。 如果您输出制表符或逗号分隔文本,则它不会检测分隔符,并在其他语言环境中,如果您与分号分开它不加载。 您可以通过在Windows设置中更改本地化格式来testing – excel然后select它。

从这个问题: 是否有可能强制Excel自动识别UTF-8 CSV文件?

答案似乎唯一的办法是使用UTF16文件编码与BOM。

还请注意,根据http://wiki.scn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator?original_fqdn=wiki.sdn.sap.com似乎如果你使用utf16-le与tab分离器然后它的工作&#x3002;

我想知道如果Excel读取sep =; 然后重新调用该方法来获取CSV文本,并丢失BOM – 我试图给出不正确的文本,我找不到任何工作,告诉excel同时采取sep和编码。

这是我使用Excel 2013进行testing的结果。

如果你使用UTF-8,那么有一个解决方法,它由BOM + data + sep =组成。

input(用UTF8编码写入)

\ufeffSome;Header;Columns Wîth;Fàncÿ;Stûff sep=;

输出 |Some|Header|Columns| |Wîth|Fàncÿ |Stûff | |sep=| | | |Some|Header|Columns| |Wîth|Fàncÿ |Stûff | |sep=| | |

解决scheme的问题是,虽然Excel解释sep=; 正确地,它在最后一行的第一列显示sep= (是的,它吞下了; )。

但是,如果你可以把文件写成UTF16-LE,那么有一个实际的解决scheme。 在不指定sep情况下使用\t分隔符,Excel将播放球。

input(用UTF16-LE编码)

\ufeffSome;Header;Columns Wîth;Fàncÿ;Stûff

输出 |Some|Header|Columns| |Wîth|Fàncÿ |Stûff | |Some|Header|Columns| |Wîth|Fàncÿ |Stûff |

我还不能写评论,但是我想谈谈Pier-Luc Gendreau的解决scheme。 虽然可以在欧洲Excel(默认情况下使用;作为分隔符)打开它,并且具有完整的utf-16LE支持,但是当指定sep=,时显然不可能使用这种技术。

解决scheme的问题是,虽然Excel解释sep =; 正确地,它在最后一行的第一列显示sep =(是的,它吞下了;)。

对我来说,如果我指定的分隔符不是默认分隔符(在我的情况下),所以我不认为Excel工作正确解释最后一行,并吞下最后一个分隔符,因为这是默认行为。

如果我错了,请纠正我