BLOB-кодировка для файла CSV - PullRequest
1 голос
/ 11 мая 2019

Я хотел бы создать файл CSV, используя blob.Файл должен быть закодирован в ANSI, но он не работает.

var blob = new Blob(["\ufeff", csvFile], { type: 'text/csv;charset=windows-1252;' });

Файл всегда создается с кодировкой UTF-8.

1 Ответ

0 голосов
/ 14 мая 2019

Да, передача USVString в конструктор Blob автоматически преобразует его в UTF-8 .

Параметр type используется только в качестве средства извлечения ресурсов в качестве Content-Type, соответствующего переданным данным. Заголовок charset содержит только подсказку о том, что такое кодировка контента, однако он не меняет контент вообще.

Одним из методов, который будет использовать эту информацию charset, является FileReader.readAsText() (если параметр encoding не задан).

const data = "é";
const blob1 = new Blob([data], {type: 'plain/text;charset=windows-1252'});
const blob2 = new Blob([data], {type: 'plain/text;'});

readAsText(blob1).then(res => console.log('read as CP-1252:', res));
readAsText(blob2).then(res => console.log('read as UTF-8:', res));

readAsArrayBuffer(blob1).then(res => console.log("actual bytes content CP-1252:", ...new Uint8Array(res)));
readAsArrayBuffer(blob2).then(res => console.log("actual bytes content UTF-8:", ...new Uint8Array(res)));


function readAsText(blob) {
  return new Promise(res => {
    const reader = new FileReader();
    reader.onload = e => res(reader.result);
    reader.readAsText(blob);
  });
}
function readAsArrayBuffer(blob) {
  return new Promise(res => {
    const reader = new FileReader();
    reader.onload = e => res(reader.result);
    reader.readAsArrayBuffer(blob);
  });
}
.as-console-wrapper {
  max-height: none!important;
}

Как видите, оба BLOB-объекта на самом деле содержат одни и те же байтовые данные: один из символов UTF-8 é.


Так что для того, что вы хотите, вам нужно сгенерировать ваши BLOB-объекты из TypedArray, который содержит ваши данные, уже закодированные как CP-1252. Раньше была возможность использовать API TextEncoder для кодирования из USVStrings в произвольные кодировки, но это было удалено из спецификаций и браузеров.

Вам нужно будет использовать библиотеку, чтобы выполнить преобразование. Здесь я буду использовать этот :

const data = new TextEncoder('windows-1252', {
  NONSTANDARD_allowLegacyEncoding: true
}).encode("é"); // now `data` is an Uint8Array
const blob1 = new Blob([data], {type: 'plain/text;charset=windows-1252'});
const blob2 = new Blob([data], {type: 'plain/text;'});

readAsText(blob1).then(res => console.log('read as CP-1252:', res));
readAsText(blob2).then(res => console.log('read as UTF-8:', res));

readAsArrayBuffer(blob1).then(res => console.log("actual bytes content CP-1252:", ...new Uint8Array(res)));
readAsArrayBuffer(blob2).then(res => console.log("actual bytes content UTF-8:", ...new Uint8Array(res)));


function readAsText(blob) {
  return new Promise(res => {
    const reader = new FileReader();
    reader.onload = e => res(reader.result);
    reader.readAsText(blob);
  });
}
function readAsArrayBuffer(blob) {
  return new Promise(res => {
    const reader = new FileReader();
    reader.onload = e => res(reader.result);
    reader.readAsArrayBuffer(blob);
  });
}
.as-console-wrapper {
  max-height: none!important;
}
<script>
  // force installation of the polyfill...
  window.TextEncoder = null;
</script>
<script src="https://cdn.jsdelivr.net/gh/inexorabletash/text-encoding/lib/encoding-indexes.js"></script>
<script src="https://cdn.jsdelivr.net/gh/inexorabletash/text-encoding/lib/encoding.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...