32

设想

  • 我的用户将从 Excel 中复制单元格(从而将其放入剪贴板)
  • 我的应用程序将从剪贴板中检索这些单元格

问题

  • 我的代码从剪贴板检索 CSV 格式
  • 但是,如果原始 Excel 内容包含像 ä (带变音符号的 a)这样的字符,则检索到的 CSV 字符串没有正确的字符(ä 最终显示为我的“正方形”)
  • 相比之下,如果我的代码从剪贴板检索 Unicode 文本格式,一切正常:ä 保留在从剪贴板检索的字符串中

源代码 - 原始 - 有问题

[STAThread]
static void Main(string[] args)
{
    var fmt_csv = System.Windows.Forms.DataFormats.CommaSeparatedValue;

    // read the CSV
    var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
    var stream = (System.IO.Stream)dataobject.GetData(fmt_csv);
    var enc = new System.Text.UTF8Encoding();
    var reader = new System.IO.StreamReader(stream,enc);
    string data_csv = reader.ReadToEnd();

    // read the unicode string
    string data_string = System.Windows.Forms.Clipboard.GetText();



}

运行示例代码时的结果

  • 复制步骤:在 Excel 中输入一些文本(我使用了“doppelgänger”这个词加上一些数字),然后简单地按 Ctrl-C 将其复制到剪贴板,然后运行上面的代码。
  • data_csv 设置为“doppelg�nger,1\r\n2,3\r\n\0”
  • data_string 设置为“doppelgänger\t1\r\n2\t3\r\n”

问题

  • 我该怎么做才能获得正确的字符?

注释

  • 是的,我知道我可以通过使用 Unicode 文本来解决这个问题。但我实际上想了解 CSV 发生了什么
  • 在检索流时使用或不使用 UTF-8 编码对结果没有影响

答案

在查看评论并密切关注 Excel 在剪贴板上为 CSV 放置的内容后,Excel 可能使用“传统”编码而不是 UTF-8 来放置内容似乎是合理的。所以我尝试使用 Windows 1252 代码页作为编码并且它工作。请参阅下面的代码

源代码 - 有答案

[STAThread]
static void Main(string[] args)
{
    var fmt_csv = System.Windows.Forms.DataFormats.CommaSeparatedValue;

    //read the CSV
    var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
    var stream = (System.IO.Stream)dataobject.GetData(fmt_csv);
    var enc = System.Text.Encoding.GetEncoding(1252);
    var reader = new System.IO.StreamReader(stream,enc);
    string data_csv= reader.ReadToEnd();

    //read the Unicode String
    string data_string = System.Windows.Forms.Clipboard.GetText();
}
4

2 回答 2

7

Excel 使用 Unicode 字符编码将字符串存储在剪贴板上。当您尝试在 ANSI 中读取字符串时得到一个正方形的原因是系统的 ANSI 代码页中没有该字符的表示。你应该只使用Unicode。如果您要处理本地化问题,那么 ANSI 麻烦多于其价值。

编辑: Joel Spolsky 写了一篇关于字符编码的精彩介绍,这绝对值得一看:每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最小值(没有借口!)

于 2009-06-09T02:48:01.950 回答
1

您将流编码为 UTF8 不起作用。元音变音的字节被转换成“替换字符”的 unicode 字符。

相反,只需查看流的数据,无需任何额外的编码指令。数据将采用 Excel 使用的某种设置格式。您应该能够通过查看 unlaut 所在的字节来判断。然后,您应该能够将其转换为 UTF-8。

最坏的情况是如果 CSV 格式化程序抛出所有不是 Ascii 的东西。在这种情况下,您也许可以编写自己的数据格式化程序。

在某些情况下,Excel 人员认为 CSV 仅表示 Ascii。请参阅http://www.tech-archive.net/Archive/Excel/microsoft.public.excel.misc/2008-07/msg02270.html

于 2009-06-09T02:47:22.700 回答