【问题标题】:StringWriter processes strange characters on csv generatedStringWriter 处理生成的 csv 上的奇怪字符
【发布时间】:2019-10-04 14:34:39
【问题描述】:

我在我们的应用程序中使用 StringWriter 时遇到了问题。 我对nosql db 进行了一次休息调用,它返回了dynamics 的列表。 我使用StringWriter 编写了一个csv 文件,其中包含我列表中的标题和记录。

我还尝试使用sealed classconstructor method 扩展StringWriter,它允许您输入编码类型作为参数。但是尝试所有可用的编码仍然会生成错误的字符。

这是我们对 StringWriter 的扩展:

public sealed class StringWriterWithEncoding : StringWriter
{
    private readonly Encoding encoding;

    public StringWriterWithEncoding() : this(Encoding.UTF8) { }

    public StringWriterWithEncoding(Encoding encoding)
    {
        this.encoding = encoding;
    }

    public override Encoding Encoding
    {
        get { return encoding; }
    }
}

这是生成 csv 文件的代码:

StringWriterWithEncoding sw = new StringWriterWithEncoding();

// Header
sw.WriteLine(string.Format("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};", "Soddisfazione", "Data Ricerca", "Categorie Cercate", "Id Utente", "Utente", "Categoria", "Id Documento", "Documento", "Id Sessione", "Testo Ricerca"));

foreach (var item in result.modelListDyn)
{
   sw.WriteLine(string.Format("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};", item.Satisfaction, item.Date, item.Cluster, item.UserId, item.Username, item.Category, item.DocumentId, HttpUtility.HtmlDecode(item.DocumentTitle.ToString()), item.SessionId, 
   item.TextSearch));
}

var response = Request.CreateResponse(HttpStatusCode.OK, sw.ToString());

response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");

return response;

当文件在包含一些文本的列中生成时,它会显示奇怪的字符: L’indennità di licenziamento del Jobs Act è incostituzionale

这是意大利语,错误的字符似乎是 à è ò ' ù 等。

任何人都可以提出解决方案? 谢谢!

更新

按照用户的建议,我开始使用 CsvHelper 我创建了一个 Class 和一个 ClassMap,但它仍然返回损坏的字符。

StringWriter sw = new StringWriter();
CsvWriter cw = new CsvWriter(sw);
using (CsvWriter csv = new CsvWriter(sw))
{
  csv.Configuration.RegisterClassMap<HistorySearchModelCsvHelperMap>();
  csv.Configuration.CultureInfo = CultureInfo.InvariantCulture;
  csv.WriteRecords(csvModelHelperList);
}

结果:

更新 2

问题是client-side,我的操作返回了正确的文本,没有损坏的字符。 当我使用 axios 获取实例调用它时触发操作。

axios.get(url, {
   headers: {
      'Accept': 'application/vnd.ms-excel',
      'Content-Type': 'application/vnd.ms-excel'
   }
})
.then(({ data }) => {
   const blob = new Blob([data], {
      type: 'application/vnd.ms-excel',
   });
   // "fileDownload" is 'js-file-download' module.
   fileDownload(blob, 'HistorySearches.csv', 'application/vnd.ms-excel');
   this.setState({ exportLoaded: true, exportLoading: false });
}).catch(() => {
   this.setState({ exportLoaded: false, exportLoading: false });
});

我读到将responseType 设置为blob,但即使传递类型:'application/vnd.ms-excel',我的 csv 文件上的字符仍然损坏。 在我的action 中,当我返回Response

// ... some code

StringWriterWithEncoding sw = new StringWriterWithEncoding();
CsvWriter cw = new CsvWriter(sw);
using (CsvWriter csv = new CsvWriter(sw))
{
    csv.Configuration.RegisterClassMap<HistorySearchModelCsvHelperMap>();
    csv.Configuration.CultureInfo = CultureInfo.InvariantCulture;
    csv.WriteRecords(csvModelHelperList);
}

return Request.CreateResponse(HttpStatusCode.OK, sw.ToString());
// response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.ms-excel");

return response;

我也尝试设置内容类型服务器端,但格式不正确。

【问题讨论】:

  • 你确定这里的文字被“污染”了吗?可能使用不同编码的响应响应,考虑搜索类似的东西。
  • 这是 2019 年,不要推出自己的 CSV 编写器。有很多nuget包,CsvHelper很不错。
  • 是的,没错,现在是 2019 年。所以我安装了 CsvHelper,除了最初的配置困难之外,它并没有解决我的问题。字符已损坏。
  • 你用记事本++打开了吗?简单的文本编辑器可以调查您的编码问题。保存或加载都应该被错误编码。
  • 是的,实际上问题出在客户端。我想我必须提出一个新问题。

标签: c# reactjs ecmascript-6 encoding stringwriter


【解决方案1】:

如果您希望能够在 Excel 中打开您的 csv,您需要使用 Windows-1255 的编码编写它。

如果您在通用文本编辑器中打开 csv,但它仍然显示不正确,我不确定出了什么问题,因为您的代码看起来很正常。

【讨论】:

    【解决方案2】:

    已解决直接在client-side。 我制作了自己的下载例程并将UTF-8 BOM 作为响应字符串的第一个值传递:

    downloadFile2(data, fileName, type="text/string") {
        // Create an invisible A element
        const a = document.createElement("a");
        a.style.display = "none";
    
        // Using "universal BOM" https://technet.microsoft.com/en-us/2yfce773(v=vs.118)
        const universalBOM = "\uFEFF";
        a.setAttribute('href', 'data:text/csv; charset=utf-8,' + encodeURIComponent(universalBOM+data));
        // Use download attribute to set set desired file name
        a.setAttribute('download', fileName);
        document.body.appendChild(a);
        // Trigger the download by simulating click
        a.click();
    
        // Cleanup
        window.URL.revokeObjectURL(a.href);
        document.body.removeChild(a);
    },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 2020-07-06
      相关资源
      最近更新 更多