簡體   English   中英

Excel CSV編碼問題

[英]Excel CSV Encoding issues

我有一個關於丹麥字符的問題,並在Excel中以CSV格式打開保存的文件。 請參見下面的代碼:

        [HttpGet]
        [Route("/progress/data.csv")]
        [Produces("text/csv")]
        public IActionResult GetCSV()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("æø;2;3;");
            Encoding encode = Encoding.UTF8;
            return File(encode.GetBytes(sb.ToString()), "text/csv", "data.csv");
        }

我正在使用.NET Core 2.1,並且此導出的結果是,兩個第一個字符æø顯示為æÃ。

我知道這是一個已知的問題,但到目前為止我還沒有找到解決方案。 在過去的4個小時中,我至少嘗試了15種不同的方法,包括使用帶/不帶BOM的UTF。 嘗試通過System.Text.Encoding.UTF8.GetPreamble(),各種MemoryStream,StreamWriter解決方案手動添加BOM表,並嘗試將Windows-1252與CodePagesEncodingProvider.Instance.GetEncoding(1252)結合使用,但沒有任何效果。 在Excel中打開此文件時,結果總是與預期不同。

有解決方案的人嗎?

嗯,問題是Excel處理BOM的方式。 您可能發現使用StreamWriter

除非另有說明,否則StreamWriter默認使用UTF8Encoding的實例。 該UTF8Encoding實例的構造沒有字節順序標記(BOM),因此其GetPreamble方法返回一個空字節數組。 此構造函數的默認UTF-8編碼在無效字節上引發異常。 此行為與Encoding.UTF8屬性中的編碼對象提供的行為不同。 要指定BOM並確定是否對無效字節拋出異常,請使用接受編碼對象作為參數的構造函數,例如StreamWriter(String,Boolean,Encoding)或StreamWriter。

所以我只是創建一個IActionResult的自定義實現:

public class Utf8ForExcelCsvResult : IActionResult
{
    public string Content{get;set;}
    public string ContentType{get;set;}
    public string FileName {get;set;}
    public Task ExecuteResultAsync(ActionContext context)
    {
        var Response =context.HttpContext.Response;
        Response.Headers["Content-Type"] = this.ContentType;
        Response.Headers["Content-Disposition"]=$"attachment; filename={this.FileName}; filename*=UTF-8''{this.FileName}";
        using(var sw = new StreamWriter(Response.Body,System.Text.Encoding.UTF8)){
            sw.Write(Content);
        }
        return Task.CompletedTask ;
    }
}

當您需要使用Excel打開這樣的csv文件時,只需返回Utf8ForExcelCsvResult

[HttpGet]
[Route("/progress/data.csv")]
[Produces("text/csv")]
public IActionResult MyFileDownload()
// public Utf8ForExcelCsvResult MyFileDownload()
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("æø;2;3;");
    sb.AppendLine("გამარჯობა");
    sb.AppendLine("ဟယ်လို");
    sb.AppendLine("ສະບາຍດີ");
    sb.AppendLine("cześć");
    sb.AppendLine("こんにちは");
    sb.AppendLine("你好");
    Console.WriteLine(sb.ToString());
    return new Utf8ForExcelCsvResult(){
        Content=sb.ToString(),
        ContentType="text/csv",
        FileName="hello.csv",
    };
}

在此處輸入圖片說明

我們可以使用Powershell通過Format-hex -path .\\hello.csv檢查csv文件的十六進制表示形式:

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   EF BB BF C3 A6 C3 B8 3B 32 3B 33 3B 0D 0A E1 83  æø;2;3;..á
00000010   92 E1 83 90 E1 83 9B E1 83 90 E1 83 A0 E1 83 AF  ááá á¯
00000020   E1 83 9D E1 83 91 E1 83 90 0D 0A E1 80 9F E1 80  ááá..áá
00000030   9A E1 80 BA E1 80 9C E1 80 AD E1 80 AF 0D 0A E0  áºáá­á¯..à
00000040   BA AA E0 BA B0 E0 BA 9A E0 BA B2 E0 BA 8D E0 BA  ºªàº°àºàº²àºàº
00000050   94 E0 BA B5 0D 0A 63 7A 65 C5 9B C4 87 0D 0A E3  ີ..czeÅ..ã
00000060   81 93 E3 82 93 E3 81 AB E3 81 A1 E3 81 AF 0D 0A  ãã«ã¡ã¯..
00000070   E4 BD A0 E5 A5 BD 0D 0A                          你好..

這里的前三個字節EF BB BF字節順序標記

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM