【问题标题】:C# non english characters like ü, ç ,é present in SQL Server database is getting translated to ü, ç, é in CSVSQL Server 数据库中的 C# 非英文字符(如 ü、ç、é)正在转换为 CSV 中的 ü、ç、é
【发布时间】:2020-08-18 06:14:49
【问题描述】:

我正在编写一份报告,以便将数据从表格移动到 CSV 格式的报告中。

下面是我的 SQL Server 数据库,其列值如下,使用非英语字符,例如 ü、ç、é。我提供了生成的 CSV 输出。我正在使用的代码也粘贴在下面。第一张图片是数据库数据。第二张图片是 Excel 报告数据。

我写了下面的代码。

public static byte[] GetMemoryStream<T>(List<T> data) where T : class
{
    Logger.Debug("Inside GetMemoryStream(), step 7");
    using (var mem = new MemoryStream())
    using (var writer = new StreamWriter(mem))
    using (var csvWriter = new CsvWriter(writer, System.Threading.Thread.CurrentThread.CurrentCulture)) // System.Threading.Thread.CurrentThread.CurrentCulture
    {                
        var options = new TypeConverterOptions { Formats = new[] { "yyyy/MM/dd HH:mm:ss" } };
        csvWriter.Configuration.TypeConverterOptionsCache.AddOptions<DateTime>(options);
        csvWriter.Configuration.Delimiter = ",";

        csvWriter.WriteHeader<T>();
        csvWriter.NextRecord();
        csvWriter.WriteRecords(data);

        writer.Flush();
        var result = Encoding.Unicode.GetString(mem.ToArray());
        //Console.WriteLine(result);
        return Encoding.Unicode.GetBytes(result);
        // return mem.ToArray();
    }

【问题讨论】:

  • 您需要告诉我们列的数据类型,以及您的数据库的排序规则(或者列,如果单独排序)。
  • 您的代码似乎假设StreamWriter 将使用Encoding.Unicode 编写。它默认使用Encoding.UTF8。但更大的问题是:为什么当mem.ToArray() 返回一个字节数组时,您是否将其转换为字符串(使用错误的编码)并返回字节?您是否尝试转换使用的编码系统?为什么不直接将Encoding.Unicode 传递给StreamWriter 构造函数?
  • @DaleK 我认为这是一条红鲱鱼。

标签: c# .net sql-server


【解决方案1】:

我不太确定您要做什么,但我想我可以写一个涵盖所有基础的答案。

首先我将解释您当前的代码在做什么:

using (var mem = new MemoryStream())
using (var writer = new StreamWriter(mem))

var result = Encoding.Unicode.GetString(mem.ToArray());
return Encoding.Unicode.GetBytes(result);

您使用的 StreamWriter constructor 将设置编写器以使用 UTF8 编码对内容进行编码:

使用 UTF-8 编码和默认缓冲区大小为指定流初始化 StreamWriter 类的新实例。

mem.ToArray() 会将内存流的内容作为字节数组 (byte[]) 返回。

然后您获取该字节数组并尝试使用Unicode 编码将其转换为string。请参阅What is the difference between UTF-8 and Unicode? 显然,作为不同的编码系统,您不能期望生成的string 与您编写的原始数据一致。

最后,您将该字符串转换为 Unicode 编码的byte[]。显然这里的数据仍然是错误的,因为我们从一个错误的副本开始。


查看您的代码,我假设发生了两件事之一:

  1. 您错误地认为 Unicode == UTF8(事实并非如此)。
  2. 您不知道您可以控制 StreamWriter 使用的编码,并且您正在尝试将它生成的 UTF8 编码数据转换为 Unicode 编码文件。

假设您想要 UTF8 编码的文本,则 1 的修复方法是简单地返回 mem.ToArray() 而无需通过 result 进行转换:

using (var mem = new MemoryStream())
using (var writer = new StreamWriter(mem))

return mem.ToArray();

2 的解决方法是简单地使用正确的编码初始化 StreamWriter(假设你想要 Unicode),然后返回 mem.ToArray()

using (var mem = new MemoryStream())
using (var writer = new StreamWriter(mem, Encoding.Unicode))

return mem.ToArray();

如果你想做一个从 UTF8 到 Unicode 的转换,你需要使用 UTF8 对字符串进行解码,然后使用 Unicode 对其进行编码:

using (var mem = new MemoryStream())
using (var writer = new StreamWriter(mem, Encoding.UTF8)) // UTF8 is default, but for clarity I've included it explicitly here.

var result = Encoding.UTF8.GetString(mem.ToArray());
return Encoding.Unicode.GetBytes(result);

这将使用 UTF8 编码从 byte[] 解码字符串,然后使用 Unicode 编码将其重新编码为 byte[]

【讨论】:

  • 您建议的以下 3 行代码让我使用 (var writer = new StreamWriter(mem, Encoding.UTF8)) var result = Encoding.Unicode.GetString(mem.ToArray) 解决了我的问题()); return Encoding.Unicode.GetBytes(result);
【解决方案2】:

下面是对我有用的一段代码

(var writer = new StreamWriter(mem, Encoding.UTF8)) 
var result = Encoding.Unicode.GetString(mem.ToArray()); 
return Encoding.Unicode.GetBytes(result);

所以现在我在 excel 表中没有得到任何 ? 或我之前得到的其他未知字符,下面是我以前的代码与我当前的代码的比较图像。并且当前的代码很棒

【讨论】:

    猜你喜欢
    • 2013-04-11
    • 2021-03-26
    • 2014-07-25
    • 2011-12-13
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多