Problemas de codificación para o ficheiro UTF8 CSV cando abre Excel e TextEdit

como @jlarson actualizado coa información que Mac era maior culpable, poderiamos obter máis información. Office for Mac ten polo menos 2011 e posteriormente, un apoio moi pobre para ler formatos Unicode ao importar ficheiros.

O soporte UTF-8 parece ser case inexistente, eu lin algúns comentarios sobre como funciona , aínda que a maioría di que non. Por desgraza, non teño Mac para probar. Entón, de novo: os propios ficheiros deberían estar ben como UTF-8, pero a importación impide o proceso.

Escribín unha proba rápida en JavaScript para exportar a porcentaxe de escape escapa de UTF-16 pequenas e grandes – / sen BOM, etc.

O código debe ser refacturado, pero debería estar ben para a proba. Podería funcionar mellor que UTF-8. Por suposto, isto tamén xeralmente significa maiores transferencias de datos, xa que calquera glifo ten dous ou catro bytes.

pode atopar un violín aquí:

NICODE EXPORT SAMPLE FIDDLE

Por favor, teña en conta que non xestiona CSV de xeito particular. É principalmente destinado a unha conversión pura ao URL de datos con UTF-8, UTF-16 BIG / Little Endian e +/- BOM. Hai unha opción no violín para substituír as comas con pestanas, pero creo que sería unha solución bastante difícil e fráxil se funciona.

Normalmente úsase como:

// Initiateencoder = new DataEnc({ mime : 'text/csv', charset: 'UTF-16BE', bom : true});// Convert data to percent escaped textencoder.enc(data);// Get resultvar result = encoder.pay();

Hai dúas propiedades de resultado do obxecto:

1.) encoder.lead

Este é o tipo MIME, conxunto de caracteres, etc. Para o URL de datos. Construído a partir de opcións pasadas ao inicializador ou tamén pode dicir .config({ ... new conf ...}).intro() para reconstruír.

data:

pode especificar Base64 , pero non hai ningunha conversión base64 (polo menos non tan lonxe).

2.) encoder.buf

Esta é unha cadea con A porcentaxe de datos escapados.

A función .pay() simplemente devolve 1.) e 2.) como un.

principal Código:

function DataEnc(a) { this.config(a); this.intro();}/** http://www.iana.org/assignments/character-sets/character-sets.xhtml* */DataEnc._enctype = { u8 : , // RFC-2781, Big endian should be presumed if none given u16be : , u16le : };DataEnc._BOM = { 'none' : '', 'UTF-8' : '%ef%bb%bf', // Discouraged 'UTF-16BE' : '%fe%ff', 'UTF-16LE' : '%ff%fe'};DataEnc.prototype = { // Basic setup config : function(a) { var opt = { charset: 'u8', mime : 'text/csv', base64 : 0, bom : 0 }; a = a || {}; this.charset = typeof a.charset !== 'undefined' ? a.charset : opt.charset; this.base64 = typeof a.base64 !== 'undefined' ? a.base64 : opt.base64; this.mime = typeof a.mime !== 'undefined' ? a.mime : opt.mime; this.bom = typeof a.bom !== 'undefined' ? a.bom : opt.bom; this.enc = this.utf8; this.buf = ''; this.lead = ''; return this; }, // Create lead based on config // data:,<data> intro : function() { var g = , c = this.charset || '', b = 'none' ; if (this.mime && this.mime !== '') g.Push(this.mime); if (c !== '') { c = c.replace(//g, '').toLowerCase(); if (DataEnc._enctype.u8.indexOf(c) > -1) { c = 'UTF-8'; if (this.bom) b = c; this.enc = this.utf8; } else if (DataEnc._enctype.u16be.indexOf(c) > -1) { c = 'UTF-16BE'; if (this.bom) b = c; this.enc = this.utf16be; } else if (DataEnc._enctype.u16le.indexOf(c) > -1) { c = 'UTF-16LE'; if (this.bom) b = c; this.enc = this.utf16le; } else { if (c === 'copy') c = ''; this.enc = this.copy; } } if (c !== '') g.Push('charset=' + c); if (this.base64) g.Push('base64'); this.lead = 'data:' + g.join(';') + ',' + DataEnc._BOM; return this; }, // Deliver pay : function() { return this.lead + this.buf; }, // UTF-16BE utf16be : function(t) { // U+0500 => %05%00 var i, c, buf = ; for (i = 0; i < t.length; ++i) { if ((c = t.charCodeAt(i)) > 0xff) { buf.Push(('00' + (c >> 0x08).toString(16)).substr(-2)); buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); } else { buf.Push('00'); buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); } } this.buf += '%' + buf.join('%'); // Note the hex array is returned, not string with '%' // Might be useful if one want to loop over the data. return buf; }, // UTF-16LE utf16le : function(t) { // U+0500 => %00%05 var i, c, buf = ; for (i = 0; i < t.length; ++i) { if ((c = t.charCodeAt(i)) > 0xff) { buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); buf.Push(('00' + (c >> 0x08).toString(16)).substr(-2)); } else { buf.Push(('00' + (c & 0xff).toString(16)).substr(-2)); buf.Push('00'); } } this.buf += '%' + buf.join('%'); // Note the hex array is returned, not string with '%' // Might be useful if one want to loop over the data. return buf; }, // UTF-8 utf8 : function(t) { this.buf += encodeURIComponent(t); return this; }, // Direct copy copy : function(t) { this.buf += t; return this; }};

Resposta anterior:

Non teño ningunha configuración para reproducir a túa, pero se o teu caso é o mesmo que iso de @ jlarson, o ficheiro resultante debe ser correcto.

Esta resposta foi un pouco longa (o temático divertido que di?), Pero discute varios aspectos da pregunta, que está a suceder (probable) e como comproba Realmente o que está a suceder de varias maneiras.

tl; DR:

É probable que o texto sexa importado como ISO-8859-1, Windows-1252 ou similar, e non como UTF-8. Forzar a aplicación para ler o ficheiro como UTF-8 por importación ou outros medios.

PS: o Unisarcher é unha boa ferramenta que ten dispoñible nesta viaxe.

A estrada longa en torno a

A forma “máis fácil” de estar 100% segura do que estamos a ver é usar un editor hexadecimal no resultado. Alternativamente, use , xxd ou similar a partir da liña de comandos para ver o ficheiro. Neste caso, a secuencia de bytes debe ser a de UTF-8 como entregada do script.

Como exemplo, se tomamos o script de Jlarson Take the data Array:

data = , 

Isto fúndase na cadea:

 name,city,state<newline> \u0500\u05E1\u0E01\u1054,seattle,washington<newline>

que se traduce por unicode a:

 name,city,state<newline> Ԁסกၔ,seattle,washington<newline>

como UTF-8 usa ASCII como base (bytes co máis alto non establecido é o mesmo que en ASCII), o único Secuencia especial nos datos de proba é “ס ס ၔ ၔ” que á súa vez é:

Code-point Glyph UTF-8---------------------------- U+0500 Ԁ d4 80 U+05E1 ס d7 a1 U+0E01 ก e0 b8 81 U+1054 ၔ e1 81 94

Mirando o vertedoiro hexadecimal do ficheiro descargado:

0000000: 6e61 6d65 2c63 6974 792c 7374 6174 650a name,city,state.0000010: d480 d7a1 e0b8 81e1 8194 2c73 6561 7474 ..........,seatt0000020: 6c65 2c77 6173 6869 6e67 746f 6e0a le,washington.

Na segunda liña que atopamos d480 d7a1 e0b8 81e1 8194 que coincide co anterior:

0000010: d480 d7a1 e0b8 81 e1 8194 2c73 6561 7474 ..........,seatt | | | | | | | | | | | | | | +-+-+ +-+-+ +--+--+ +--+--+ | | | | | | | | | | | | | | | | Ԁ ס ก ၔ , s e a t t

Ningún dos outros personaxes é destruído.

Fai probas similares se o desexa. O resultado debe ser o similar.

por mostra proporcionada â € œAT, â € œ

Tamén podemos botar unha ollada á mostra proporcionada na pregunta. É probable que supoña que o texto está representado en Excel / TextEdit na páxina de código 1252.

para citar a Wikipedia en Windows-1252:

Windows-1252 ou CP-1252 é unha codificación de caracteres do alfabeto latino, utilizado por defecto nos compoñentes legados de Microsoft Windows en inglés e algunhas outras linguas occidentais. É unha versión dentro do grupo de páxinas de código de Windows. Nos paquetes de látex, é referido como “ansinew”.

Recuperar os bytes orixinais

Para traducir-lo de novo no seu formulario orixinal, podemos ver o deseño da páxina de código, desde onde Obtemos:

Character: <â> <€> <”> <,> < > <â> <€> < > <,> < > <â> <€> <œ>U.Hex : e2 20ac 201d 2c 20 e2 20ac 9d 2c 20 e2 20ac 153T.Hex : e2 80 94 2c 20 e2 80 9d* 2c 20 e2 80 9c
  • U é a abreviatura de Unicode
  • é a abreviatura traducida

Por exemplo:

â => Unicode 0xe2 => CP-1252 0xe2” => Unicode 0x201d => CP-1252 0x94€ => Unicode 0x20ac => CP-1252 0x80

Cases Specials Como 9d Non ten un código de código correspondente no CP-1252, simplemente copialos directamente.

Nota: Se notas a cadea danada copiando o texto en Un ficheiro e facer un vertedoiro hexadecimal, gardar o ficheiro, por exemplo, con codificación UTF-16 para obter valores de Unicode xa que están representados na táboa. Por exemplo En Vim:

set fenc=utf-16# Orset fenc=ucs-2

bytes a UTF-8

Entón combinamos o resultado, o T.Hex, en UTF-8. Nas secuencias UTF-8, os bytes están representados por un byte principal dinos cantos bytes posteriores forman o glifo. Por exemplo, se un byte ten o valor binario 110x xxxx, sabemos que este byte e os seguintes representan un punto de código. Un total de dous. 1110 xxxx Díganos que son tres e así por diante. Os valores ASCII non teñen o bit de alta definición, polo que calquera bbf93A854E “> é independente. Un total de byte.

0xe2 = 1110 0010compartimiento => 3 bytes => 0xe28094 (em-dash) - 0x2c = 0010 1100compartimiento => 1 byte => 0x2c (coma), 0x2c = 0010 0000compartimiento => 1 byte => 0x20 (espacio) 0xe2 = 1110 0010compartimiento => 3 bytes => 0xe2809d (d-derecha) ” 0x2c = 0010 1100compartimiento => 1 byte => 0x2c (coma), 0x2c = 0010 0000compartimiento => 1 byte => 0x20 (espacio) 0xe2 = 1110 0010compartimiento => 3 bytes => 0xe2809c (izquierda-dq) "

Conclusión; A cadea orixinal UTF-8 foi:

—, ”, "

devolvelo

Tamén podemos facer o contrario. A cadea orixinal como bytes:

UTF-8: e2 80 94 2c 20 e2 80 9d 2c 20 e2 80 9c

Valores correspondentes en CP-1252:

e2 => â80 => €94 => ”2c => ,20 => <space>...

e así por diante, resultado:

—, â€, “

Importación de MS Excel

Noutras palabras: o problema en cuestión podería ser como facer Importar ficheiros de texto UTF-8 en MS Excel e algunhas outras aplicacións. En Excel isto pódese facer de varias maneiras.

  • Método One:

Non gardar o ficheiro cunha extensión recoñecida pola aplicación, como .csv ou .txt, pero omite completamente ou inventar algo.

Como exemplo, garde o ficheiro como "testfile", sen extensión. A continuación, en Excel, abra o ficheiro, confirme que realmente queremos abrir este ficheiro e voilà recibimos a opción de codificación. Seleccione UTF-8 e o ficheiro debe ser lido correctamente.

  • Método dous:

Use datos de importación en vez de abrir o ficheiro. Algo así como :.

Data -> Import External Data -> Import Data

Seleccione o conxunto de caracteres e continúe

Asegúrese de que o Excel ea fonte seleccionada realmente apoiar glifo

Tamén podemos probar a compatibilidade de fontes para personaxes Unicode usando o portapapeis, ás veces, máis amigables. Por exemplo, copie o texto desta páxina en Excel:

  • páxina con puntos de código U + 0E00 a u + 0eff

Se hai soporte para os puntos de código , o texto debe ser amosado correctamente.

Linux

en Linux, que é principalmente UTF-8 na área de usuario, isto non debe ser un problema. Usando Calc de oficina gratuíto, VIM, etc. amosar os ficheiros correctamente prestados.

Por que funciona (ou debe)

codeuri dos estados de especificación (Ler tamén SEC-15.1. ):

A función codeuri calcula unha nova versión dun URI no que cada instancia de determinados caracteres é substituído por unha, dúas, tres ou catro secuencias de escape representando a codificación UTF-8 de carácter.

Podemos simplemente probar isto na nosa consola, por exemplo, dicindo:

>> encodeURI('Ԁסกၔ,seattle,washington')<< "%D4%80%D7%A1%E0%B8%81%E1%81%94,seattle,washington"

Cando rexistramos, as secuencias de escape son iguais ás do Dump Hexadecimal anterior:

%D4%80%D7%A1%E0%B8%81%E1%81%94 (encodeURI in log) d4 80 d7 a1 e0 b8 81 e1 81 94 (hex-dump of file)

O, probando un código de 4 bytes:

>> encodeURI('????')<< "%F3%B1%80%81"

Se isto non cumpre

Se ningún deles aplícase pode axudar se engade

  1. mostra de entrada esperada vs saída danada (copia de pegar).
  2. Exemplo de dor hexadeecimal de ACH IVO de resultados orixinais de datos.

Deixa unha resposta

O teu enderezo electrónico non se publicará Os campos obrigatorios están marcados con *