Excel CSV Проблемы с кодировкой - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть вопрос о датских символах и открыть сохраненный файл в формате CSV в Excel.См. Код ниже:

        [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 разных способов, в том числе UTF с / без спецификации.При добавлении спецификации вручную с помощью System.Text.Encoding.UTF8.GetPreamble (), различных решений MemoryStream, StreamWriter пробовали использовать windows-1252 с CodePagesEncodingProvider.Instance.GetEncoding (1252), но ничего не работает.При открытии этого файла в Excel результат всегда отличается от ожидаемого.

У кого есть решение для этого?

1 Ответ

0 голосов
/ 25 сентября 2018

Ну, проблема в том, как Excel справиться с спецификацией.Возможно, вы обнаружите, что StreamWriter:

StreamWriter по умолчанию использует экземпляр UTF8Encoding, если не указано иное.Этот экземпляр UTF8Encoding создается без метки порядка байтов (BOM), поэтому его метод GetPreamble возвращает пустой байтовый массив.Кодировка UTF-8 по умолчанию для этого конструктора создает исключение для недопустимых байтов.Это поведение отличается от поведения, предоставляемого объектом кодирования в свойстве Encoding.UTF8.Чтобы указать спецификацию и определить, генерируется ли исключение для недопустимых байтов, используйте конструктор, который принимает объект кодирования в качестве параметра, например 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 ;
    }
}

Когда вам нужно открыть такой CSV-файл в Excel, просто верните 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",
    };
}

enter image description here

Мы можем использовать Powershell для проверки HEX-представления CSV-файла с помощью Format-hex -path .\hello.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 являются метками порядка байтов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...