【问题标题】:Line breaks in generated csv file driving me crazy生成的 csv 文件中的换行符让我发疯
【发布时间】:2011-08-22 13:29:06
【问题描述】:

我正在尝试导出我拥有的一些数据(存储在数据表中)。其中一些值中有换行符。现在每次我尝试在 excel (2010) 中导入文件时,linbreaks 都会被识别为新行,而不是实际的换行符。

我已经搜索了几个小时,看到了很多解决方案,但我似乎无法修复它。

我输出 csv 文件的方式: (变量 csvfile 是一个字符串生成器)

context.Response.Clear();
context.Response.ContentType = "text/csv";
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + name + ".csv");
context.Response.Write(csvfile.ToString());
context.Response.End();

当我用 excel 手动打开它时,它显示正常。但是因为excel 2003不支持文件格式,所以我必须导入它。通过导入,它会将换行符(字段中的 \n)视为新行。

很遗憾,我不能给你一个我使用的真实数据的例子(这都是个人数据),但我可以给你一个例子来说明它是如何出错的:

Header1,Header2,Header3
"value1","value2","value 3
and this is where its going wrong"

这是一个简单的 csv 文件,当您导入它时,您会看到哪里出错了。我默认用双引号封装字段。默认情况下,我还会从值中删除前导空格。

我在这个看似简单的问题上花费了至少 2 天时间,但对于我的一生,我无法弄清楚如何解决它。我在同一个问题上看到了多个主题,但那里提供的解决方案似乎都没有解决这个问题。

【问题讨论】:

标签: c# excel-2010 csv


【解决方案1】:

这对我有用:

a) 设置 Response.ContentEncoding = System.Text.Encoding.UTF8 不足以使 Excel 正确打开 UTF-8 文件。相反,您必须手动为 excel 文件编写字节顺序标记 (BOM) 标头:

if (UseExcel2003Compatibility)
    {
        // write UTF-16 BOM, even though we export as utf-8. Wrong but *I think* the only thing Excel 2003 understands
        response.Write('\uFEFF');
    }
    else
    {
        // use the correct UTF-8 bom. Works in Excel 2008 and should be compatible to all other editors
        // capable of reading UTF-8 files
        byte[] bom = new byte[3];
        bom[0] = 0xEF;
        bom[1] = 0xBB;
        bom[2] = 0xBF;
        response.BinaryWrite(bom);
    }

b) 作为八位字节流发送,使用带有 .csv 扩展名的文件名,并按照 HTTP 规范的要求引用文件名:

response.ContentType = "application/octet-stream";
response.AppendHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

c) 对所有字段使用双引号

我刚刚检查过,对于我来说,Excel 可以正确打开下载的文件,包括带有换行符的字段。

但请注意,Excel 仍无法在默认分隔符不同于“,”的所有系统上正确打开此类 CSV。例如。如果用户在设置为德语区域设置的 Windows 系统上运行 Excel,Excel 将无法正确打开文件,因为它需要分号而不是逗号作为分隔符。我不认为有什么可以做的。

【讨论】:

  • 其实有,但它是一个非常晦涩的功能。您可以将其写为 csv 中的第一行:sep=,它将使 Excel 使用相同的分隔符,而不管区域设置。
  • 很好,我不知道这个。谢谢。
  • @MichaelBöckling 你先生是救生员!.. 我一直在寻找解决这个问题的简单方法
【解决方案2】:

第 1 步: 在需要将文本值分到下一行的地方使用“\n”,如下所示。

String value = "我不怕练过一万脚的人,\n我怕练过一脚一万次的人。";

第 2 步: 使用扩展方法。它将检查文本索引以破坏文本值。

public static class ExtensionMethods
{
    static char[] SpecialCharacters = new char[] { ',', '"', '\r', '\n' };
    public static string ToWrap(this string val)
    {
        StringBuilder builder = new StringBuilder();
        bool firstColumn = true;

        // Add separator if this isn't the first value
        if (!firstColumn)
            builder.Append(',');
        // Implement special handling for values that contain comma or quote
        // Enclose in quotes and double up any double quotes
        if (val.IndexOfAny(SpecialCharacters) != -1)
            builder.AppendFormat("\"{0}\"", val.Replace("\"", "\"\""));
        else
            builder.Append(val);
        firstColumn = false;

        return builder.ToString();
    }
}

第 3 步: 创建扩展方法后。使用字符串变量中的扩展方法来包装文本值。

Value.ToWrap();

【讨论】:

    【解决方案3】:

    只要字段正确双引号,您就可以在 CSV 文件中使用换行符。这里的问题似乎是让 Excel 正确导入记录。

    这个问题之前已经在网站上提出过,有几个可能的解决方案:

    • 将输出文件的编码设置为 ASCII 或 UTF-8。由于您在问题中将其设置为 UTF-8,因此请尝试使用 ASCII。 (link)

    • 将文件名更改为.csv,这可能会诱使 Excel 正确导入文件 (link)

    【讨论】:

    • 恐怕我也尝试过 ASCII,但没有结果。我知道这个问题已经被问过,甚至多次。我已经阅读并尝试了每一个解决方案,但由于某种原因它不想正确导入。
    【解决方案4】:

    我认为您不能在 CSV 字段中使用换行符,因为换行符表示新记录。在将字段值添加到字符串之前,您可以替换字段值中的所有换行符吗?或者您可以构建一个 Excel 文件,它们应该允许在字段中使用换行符。

    【讨论】:

    • CSV 文件允许在字段中有换行符。
    【解决方案5】:

    包含 BOM 的 UTF 文件将导致 Excel 按字面意思处理新行,即使该字段被引号包围。 (测试 Excel 2008 Mac)

    解决方案是将任何新行设为回车符 (CHR 13) 而不是换行符。

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题。我在浏览 this blog 部分时找到了解决方案 - “以正确的格式导出到 Excel:”

      我修改我的代码如下:

      string brstyle = @"<style>br { mso-data-placement:same-cell; }</style>";
      
      Response.Write(brstyle);
      
      Response.Write(stringWriter.ToString());
      

      它对我有用。现在带有换行符的文本出现在单个单元格中,而不是每个换行符的新单元格(行)中。

      【讨论】:

        猜你喜欢
        • 2011-11-18
        • 1970-01-01
        • 2011-05-30
        • 2012-11-02
        • 2020-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多