我正在尝试导出一些数据(存储在数据表中)。其中一些值中包含换行符。现在,每当我尝试在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天,但对于我的生活,我无法弄清楚我是如何解决这个问题的。我在同一个问题上看到过多个主题,但那里提供的解决方案似乎都无法解决这个问题。
答案 0 :(得分:3)
这对我有用:
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)以octet-stream发送,使用扩展名为.csv的文件名,并根据HTTP规范的要求引用文件名:
response.ContentType = "application/octet-stream";
response.AppendHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
c)对所有字段使用双引号
我刚检查过并且对我来说Excel正确打开了这样的下载文件,包括换行符的字段。
但请注意,Excel仍然无法在默认分隔符与“,”不同的所有系统上正确打开此类CSV。例如。如果用户在设置为德语区域设置的Windows系统上运行Excel,则Excel将无法正确打开文件,因为它需要使用分号而不是逗号作为分隔符。我认为没有什么可以做的。
答案 1 :(得分:1)
我认为您不能在CSV字段中添加换行符,因为换行符表示新记录。在将字段值添加到字符串之前,是否可以替换字段值中的所有换行符?或者也许您可以构建一个Excel文件,它们应该允许字段中的换行符。
答案 2 :(得分:1)
只要字段被正确双引号,就可以在CSV文件中包含换行符。这里的问题似乎是让Excel正确导入记录。
之前已经在网站上询问了这一点,并提供了一些可能的解决方案:
答案 3 :(得分:0)
包含BOM的UTF文件将导致Excel在字面上处理新行,即使该字段被引号括起来也是如此。 (经过测试的Excel 2008 Mac)
解决方法是将任何新行换回(CHR 13)而不是换行。
答案 4 :(得分:0)
我遇到了同样的问题。我在浏览this blog时在“使用正确的格式导出到Excel:”
部分中找到了解决方案我按如下方式修改了我的代码:
string brstyle = @"<style>br { mso-data-placement:same-cell; }</style>";
Response.Write(brstyle);
Response.Write(stringWriter.ToString());
它对我有用。现在,包含换行符的文本出现在单个单元格中,而不是出现在每个换行符的新单元格(行)中。
答案 5 :(得分:0)
步骤1: 使用“ \ n”在需要将文本值中断到下一行的地方,如下所示。
字符串值=“我不怕练习过10,000次踢球的人,\ n,但我怕练习过10,000次踢球的人。”
步骤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();