StringWriter обрабатывает странные символы в сгенерированном CSV - PullRequest
0 голосов
/ 04 октября 2019

У меня проблемы с использованием StringWriter в нашем приложении. Я делаю вызов покоя через nosql db, и он возвращает список dynamics. Я использую StringWriter для записи csv файла, который содержит заголовок и записи из моего списка.

Я также попытался расширить StringWriter с помощью sealed class с помощью constructor method, который позволяет вам ввестиТип кодирования в качестве параметра. Но пробуя все доступные кодировки, он по-прежнему генерирует неправильные символы.

Это наше расширение 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);
}

Результат: enter image description here

ОБНОВЛЕНИЕ 2

Проблема client-side, мои действия возвращают правильный текст без прерываниясимволы. Действие запускается, когда я вызываю его с экземпляром axios get.

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;

Я пытался установить тип контента и на стороне сервера, но формат все равно неверный.

### Решено ###

Решено непосредственно на 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);
},

1 Ответ

0 голосов
/ 04 октября 2019

Если вы хотите иметь возможность открыть свой CSV в Excel, вам нужно написать его с кодировкой Windows-1255.

Если вы открываете CSV в универсальном текстовом редакторе, и он по-прежнему отображается неправильноЯ не уверен, что не так, поскольку ваш код выглядит вменяемым.

...