c#,Excel + csv:如何获得正确的编码?

时间:2010-07-27 18:10:05

标签: c# excel encoding csv export

我现在已经尝试了很长一段时间,但无法理解。我正在尝试通过* .csv文件将数据导出到Excel。它到目前为止工作得很好,但在Excel中打开文件时遇到了一些编码问题。

(左边的原始字符串,右边的EXCEL结果):

Messwert(µm / m) ==> Messwert(µm / m)

Dümme Mässöng ==> Dümme Mässöng

Notepad ++告诉我该文件被编码为“ANSI as UTF8”(WTF?)

所以我尝试获得有效结果的方法不同: 明显的实施:

tWriter.Write(";Messwert(µm /m)");

更复杂的一个(尝试了十几个或更多编码组合:):

tWriter.Write(Encoding.Default.GetString(Encoding.Unicode.GetBytes(";Messwert(µm /m)")));
tWriter.Write(Encoding.ASCII.GetString(Encoding.Unicode.GetBytes(";Messwert(µm /m)")));

等等

创建数据的方法的完整源代码:

    MemoryStream tStream = new MemoryStream();
    StreamWriter tWriter = new StreamWriter(tStream);
    tWriter.Write("\uFEFF");

    tWriter.WriteLine(string.Format("{0}", aMeasurement.Name));
    tWriter.WriteLine(aMeasurement.Comment);
    tWriter.WriteLine();
    tWriter.WriteLine("Zeit in Minuten;Messwert(µm / m)");

    TimeSpan tSpan;
    foreach (IMeasuringPoint tPoint in aMeasurement)
    {
        tSpan = new TimeSpan(tPoint.Time - aMeasurement[0].Time);
        tWriter.WriteLine(string.Format("{0};{1};", (int)tSpan.TotalMinutes, getMPString(tPoint)));
    }

    tWriter.Flush();
    return tStream;

生成的CSV文件:

Dümme Mössäng
Testmessung die erste

Zeit in Minuten;Messwert(µm / m)
0;-703;
0;-381;
1;1039;
1;1045;
2;1457;
2;1045;

7 个答案:

答案 0 :(得分:8)

这个solution被编写为Java应用程序的修复程序,但您应该可以在C#中执行类似的操作。您可能还想查看StreamWriter类的文档,它在引用字节顺序标记(BOM)的备注中。

答案 1 :(得分:7)

这对我来说很完美:

private const int WIN_1252_CP = 1252; // Windows ANSI codepage 1252

    this._writer = new StreamWriter(fileName, false, Encoding.GetEncoding(WIN_1252_CP));

CSV encoding issues (Microsoft Excel)

答案 2 :(得分:5)

尝试以下方法:

using (var sw = File.Create(Path.Combine(txtPath.Text, "UTF8.csv")))
{
  var preamble = Encoding.UTF8.GetPreamble();
  sw.Write(preamble, 0, preamble.Length);
  var data = Encoding.UTF8.GetBytes("懘荧,\"Hello\",text");
  sw.Write(data, 0, data.Length);
}

在写入UTF8编码的CSV之前,它会将正确的UTF8前导码写入文件。

答案 3 :(得分:3)

  

“ANSI as UTF8”(WTF?)

NotePad ++可能是正确的。编码是UTF8(即正确的Unicode标头),但只包含ANSI数据(即,é不是以正确的UTF8方式编码,这意味着两个字节)。

或者:它是相反的方式。它是ANSI(没有文件头BOM),但单个字符的编码是或看起来像UTF8。这可以解释ü和其他角色在不止一个其他角色中的扩展。您可以通过强制将文件读取为Unicode来解决此问题。

如果可以发布(部分)您的CSV,我们可以帮助修复它。

修改

现在我们已经看到了您的代码:您可以删除StreamWriter并将其替换为TextWriter吗?另外,删除BOM的手工编码,没有必要。创建TextWriter时,可以指定编码(不要使用ASCII,请尝试使用UTF8)。

答案 4 :(得分:2)

我建议您在十六进制编辑器中打开文本文件,看看它到底是什么。 UTF-16的BOM是0xFEFF,写入代码显然是写入流 - 但写入的其余部分没有指定要使用的编码 - 它将使用StreamWriter的默认编码,即UTF-8 。似乎混合了编码。

当您以十六进制视图弹出文件时,如果在字符之间看到大量的0x00,则表示您使用的是UTF-16,即C#中的Encoding.Unicode。如果字符之间没有0x00,则编码可能是UTF-8。

如果是后一种情况,只需将BOM修正为EF BB BF而不是FE FF,并使用UTF-8编码正常读取。

答案 5 :(得分:2)

Trevor Germain帮助我以正确的编码格式保存

using (var sw = File.Create(Path.Combine(txtPath.Text, "UTF8.csv")))
{
    var preamble = Encoding.UTF8.GetPreamble();  
    sw.Write(preamble, 0, preamble.Length);  
    var data = Encoding.UTF8.GetBytes("懘荧,\"Hello\",text");  
    sw.Write(data, 0, data.Length);
}

答案 6 :(得分:0)

对于使用StreamWriter的场景,我发现显式将UTF8编码传递给启用StreamWriter的excel,以使用正确的编码读取文件。

有关详细信息,请参阅此答案: https://stackoverflow.com/a/22306937/999048