utf8 formato convertir bom archivos abrir php csv utf-8 byte-order-mark

php - formato - utf 8 sin bom c#



¿Cómo puedo generar un CSV UTF-8 en PHP que Excel leerá correctamente? (30)

Tengo algo muy simple que solo genera algunas cosas en formato CSV, pero tiene que ser UTF-8. Abrí este archivo en TextEdit o TextMate o Dreamweaver y muestra los caracteres UTF-8 correctamente, pero si lo abro en Excel está haciendo este tipo de cosas absurdas en su lugar. Esto es lo que tengo al principio de mi documento:

header("content-type:application/csv;charset=UTF-8"); header("Content-Disposition:attachment;filename=/"CHS.csv/"");

Todo esto parece tener el efecto deseado, excepto que Excel (Mac, 2008) no quiere importarlo correctamente. No hay opciones en Excel para "abrir como UTF-8" o algo así, así que ... Me estoy molestando un poco.

Parece que no puedo encontrar ninguna solución clara para esto en ninguna parte, a pesar de que mucha gente tiene el mismo problema. Lo que más veo es incluir la lista de materiales, pero no puedo encontrar la manera de hacerlo. Como puede ver arriba, solo estoy haciendo echo de estos datos, no estoy escribiendo ningún archivo. Puedo hacer eso si es necesario, simplemente no lo hago porque no parece que sea necesario en este punto. ¿Alguna ayuda?

Actualización: Intenté hacer eco de la BOM como echo pack("CCC", 0xef, 0xbb, 0xbf); que acabo de sacar de un sitio que intentaba detectar la lista de materiales. Pero Excel simplemente agrega esos tres caracteres a la primera celda cuando importa, y aún daña los caracteres especiales.


Esto funciona bien en excel tanto para Windows como para Mac OS.

Soluciona problemas en excel que no muestran caracteres que contienen diacríticos, letras cirílicas, letras griegas y símbolos de moneda.

function writeCSV($filename, $headings, $data) { //Use tab as field separator $newTab = "/t"; $newLine = "/n"; $fputcsv = count($headings) ? ''"''. implode(''"''.$newTab.''"'', $headings).''"''.$newLine : ''''; // Loop over the * to export if (! empty($data)) { foreach($data as $item) { $fputcsv .= ''"''. implode(''"''.$newTab.''"'', $item).''"''.$newLine; } } //Convert CSV to UTF-16 $encoded_csv = mb_convert_encoding($fputcsv, ''UTF-16LE'', ''UTF-8''); // Output CSV-specific headers header(''Set-Cookie: fileDownload=true; path=/''); //This cookie is needed in order to trigger the success window. header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=/"$filename.csv/";" ); header("Content-Transfer-Encoding: binary"); header(''Content-Length: ''. strlen($encoded_csv)); echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/excel exit; }


¿El problema persiste cuando lo guarda como un archivo .txt y lo abre en Excel con una coma como delimitador?

El problema puede no ser la codificación en absoluto, puede ser que el archivo no sea un CSV perfecto según los estándares de Excel.


¿Qué tal solo generar resultados para Excel? PHPExcel que le permite generar archivos XLS en el servidor. Lo uso con frecuencia para los clientes que no pueden "descifrar" las csv y hasta ahora nunca han tenido una queja. También permite algún formato adicional (sombreado, alturas de fila, cálculos, etc.) que csv nunca hará.


Añadir:

fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));

O:

fprintf($file, "/xEF/xBB/xBF");

Antes de escribir cualquier contenido en el archivo CSV.

Ejemplo:

<?php $file = fopen( "file.csv", "w"); fprintf( $file, "/xEF/xBB/xBF"); fputcsv( $file, ["english", 122, "বাংলা"]); fclose($file);


Acabo de lidiar con el mismo problema, y ​​se me ocurrió dos soluciones.

  1. Use la clase PHPExcel como lo sugiere bpeterson76 .

    • El uso de esta clase genera el archivo más compatible, pude generar un archivo a partir de datos codificados UTF-8 que se abrieron bien en Excel 2008 Mac, Excel 2007 Windows y Google Docs.
    • El mayor problema con el uso de PHPExcel es que es lento y usa mucha memoria, lo que no es un problema para archivos de tamaño razonable, pero si su archivo Excel / CSV tiene cientos o miles de filas, esta biblioteca se vuelve inutilizable .
    • Aquí hay un método PHP que tomará algunos datos TSV y generará un archivo Excel en el navegador, tenga en cuenta que utiliza el Escritor Excel5, lo que significa que el archivo debe ser compatible con las versiones anteriores de Excel, pero ya no tengo acceso a ninguno, así que no puedo probarlos.

      function excel_export($tsv_data, $filename) { $export_data = preg_split("//n/", $tsv_data); foreach($export_data as &$row) { $row = preg_split("//t/", $row); } include("includes/PHPExcel.php"); include(''includes/PHPExcel/Writer/Excel5.php''); $objPHPExcel = new PHPExcel(); $objPHPExcel->setActiveSheetIndex(0); $sheet = $objPHPExcel->getActiveSheet(); $row = ''1''; $col = "A"; foreach($export_data as $row_cells) { if(!is_array($row_cells)) { continue; } foreach($row_cells as $cell) { $sheet->setCellValue($col.$row, $cell); $col++; } $row += 1; $col = "A"; } $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); header(''Content-Type: application/vnd.ms-excel''); header(''Content-Disposition: attachment;filename="''.$filename.''.xls"''); header(''Cache-Control: max-age=0''); $objWriter->save(''php://output''); exit; }

  2. Debido a los problemas de eficiencia con PHPExcel, también tuve que descubrir cómo generar un archivo CSV o TSV compatible con UTF-8 y Excel.

    • Lo mejor que se me ocurrió fue un archivo que era compatible con Excel 2008 Mac y Excel 2007 PC, pero no con Google Docs, que es lo suficientemente bueno para mi aplicación.
    • Encontré la solución here , específicamente, esta respuesta , pero también debería leer la respuesta aceptada, ya que explica el problema.
    • Aquí está el código PHP que utilicé, tenga en cuenta que estoy usando datos tsv (pestañas como delimitadores en lugar de comas):

      header ( ''HTTP/1.1 200 OK'' ); header ( ''Date: '' . date ( ''D M j G:i:s T Y'' ) ); header ( ''Last-Modified: '' . date ( ''D M j G:i:s T Y'' ) ); header ( ''Content-Type: application/vnd.ms-excel'') ; header ( ''Content-Disposition: attachment;filename=export.csv'' ); print chr(255) . chr(254) . mb_convert_encoding($tsv_data, ''UTF-16LE'', ''UTF-8''); exit;


Acabo de probar estos encabezados y obtuve Excel 2013 en una PC con Windows 7 para importar correctamente el archivo CSV con caracteres especiales. La Marca de Orden de Byte (BOM) fue la clave final que lo hizo funcionar.

header(''Content-Encoding: UTF-8''); header(''Content-type: text/csv; charset=UTF-8''); header("Content-disposition: attachment; filename=filename.csv"); header("Pragma: public"); header("Expires: 0"); echo "/xEF/xBB/xBF"; // UTF-8 BOM


Así es como lo hice (eso es para que el navegador descargue el archivo csv):

header(''Content-Description: File Transfer''); header(''Content-Type: application/octet-stream''); header(''Content-Disposition: attachment; filename=file.csv''); header(''Content-Transfer-Encoding: binary''); header(''Expires: 0''); header(''Cache-Control: must-revalidate, post-check=0, pre-check=0''); header(''Pragma: public''); echo "/xEF/xBB/xBF"; // UTF-8 BOM echo $csv_file_content; exit();

Lo único que solucionó el problema de codificación UTF8 en la vista previa de CSV cuando pulsas la barra espaciadora en Mac ... pero no en Excel Mac 2008 ... no sé por qué


Como la codificación UTF8 no funciona bien con Excel. Puede convertir los datos a otro tipo de codificación usando iconv() .

p.ej

iconv(''UTF-8'', ''ISO-8859-1//TRANSLIT'', $value),


De lo contrario, usted puede:

header("Content-type: application/x-download"); header("Content-Transfer-Encoding: binary"); header("Content-disposition: attachment; filename=".$fileName.""); header("Cache-control: private"); echo utf8_decode($output);


El elemento de archivo CSV incluye una marca de orden de bytes.

O como se sugirió y la solución simplemente lo repite con el cuerpo HTTP


En mi caso, el seguimiento funciona muy bien para hacer que el archivo CSV con caracteres UTF-8 se muestre correctamente en Excel.

$out = fopen(''php://output'', ''w''); fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF)); fputcsv($out, $some_csv_strings);

El 0xEF 0xBB 0xBF BOM le permitirá a Excel conocer la codificación correcta.


Estaba teniendo el mismo problema y se resolvió de la siguiente manera:

header(''Content-Encoding: UTF-8''); header(''Content-Type: text/csv; charset=utf-8'' ); header(sprintf( ''Content-Disposition: attachment; filename=my-csv-%s.csv'', date( ''dmY-His'' ) ) ); header(''Content-Transfer-Encoding: binary''); header(''Expires: 0''); header(''Cache-Control: must-revalidate, post-check=0, pre-check=0''); header(''Pragma: public''); $df = fopen( ''php://output'', ''w'' ); //This line is important: fputs( $df, "/xEF/xBB/xBF" ); // UTF-8 BOM !!!!! foreach ( $rows as $row ) { fputcsv( $df, $row ); } fclose($df); exit();


Este post es bastante viejo, pero después de horas de intentarlo, quiero compartir mi solución ... quizás ayude a alguien que lidia con Excel y Mac y CSV y tropieza con esta amenaza. Estoy generando un csv dinámicamente como salida de una base de datos con usuarios de Excel en mente. (UTF-8 con BOM)

Probé muchos íconos, pero no pude usar las abreviaturas alemanas para trabajar en Mac Excel 2004. Una solución: PHPExcel. Es genial, pero para mi proyecto demasiado. Lo que funciona para mí es crear el archivo csv y convertir este archivo csv a xls con este PHPsnippet: csv2xls . el resultado xls funciona con excel german umlauts (ä, ö, Ü, ...).


Estoy en Mac, en mi caso solo tenía que especificar el separador con "sep=;/n" y codificar el archivo en UTF-16LE de esta manera:

$data = "sep=;/n" .mb_convert_encoding($data, ''UTF-16LE'', ''UTF-8'');


Excel no es compatible con UTF-8. Tienes que codificar tu texto UTF-8 en UCS-2LE.

mb_convert_encoding($output, ''UCS-2LE'', ''UTF-8'');


Mientras investigaba y descubrí que UTF-8 no funciona bien en MAC y Windows, así que lo intenté con Windows-1252, es compatible con ambos, pero debe seleccionar el tipo de codificación en ubuntu. Aquí está mi código $valueToWrite = mb_convert_encoding($value, ''Windows-1252'');

$response->headers->set(''Content-Type'', $mime . ''; charset=Windows-1252''); $response->headers->set(''Pragma'', ''public''); $response->headers->set(''Content-Endcoding'',''Windows-1252''); $response->headers->set(''Cache-Control'', ''maxage=1''); $response->headers->set(''Content-Disposition'', $dispositionHeader); echo "/xEF/xBB/xBF"; // UTF-8 BOM


No es necesario convertir texto ya codificado en utf-8 utilizando mb_convert_encoding . Simplemente agregue tres caracteres en frente del contenido original:

$newContent = chr(239) . chr(187) . chr(191) . $originalContent

Para mí, esto resolvió el problema de los caracteres especiales en los archivos csv.


Para citar a un ingeniero de soporte de Microsoft ,

Excel para Mac actualmente no es compatible con UTF-8

Actualización, 2017 : esto es cierto para todas las versiones de Microsoft Excel para Mac antes de Office 2016 . Las versiones más nuevas (desde Office 365) ahora son compatibles con UTF-8.

Para poder generar el contenido UTF-8 que Excel tanto en Windows como OS X podrá leer con éxito, deberá hacer dos cosas:

  1. Asegúrese de convertir su texto UTF-8 a UTF-16LE

    mb_convert_encoding($csv, ''UTF-16LE'', ''UTF-8'');

  2. Asegúrese de agregar la marca de orden de bytes UTF-16LE

    chr(255) . chr(254)

El siguiente problema que aparece solo con Excel en OS X (pero no en Windows) será cuando vea un archivo CSV con valores separados por comas, Excel representará las filas solo con una fila y todo el texto junto con las comas de la primera fila.

La forma de evitar esto es usar pestañas como su valor separado.

Utilicé esta función a partir de los comentarios de PHP (usando pestañas "/ t" en lugar de comas) y funcionó perfectamente en OS X y Windows Excel.

Tenga en cuenta que para solucionar un problema con una columna vacía al final de una fila, tuve que cambiar la línea de código que dice:

$field_cnt = count($fields);

a

$field_cnt = count($fields)-1;

Como dicen algunos de los otros comentarios en esta página, otras aplicaciones de hoja de cálculo como OpenOffice Calc, los propios números de Apple y la hoja de cálculo de Google Docs no tienen problemas con los archivos UTF-8 con comas.

Consulte la tabla en esta pregunta para saber qué funciona y qué no funciona para los archivos CSV Unicode en Excel

Como nota al margen, podría agregar que si estás utilizando Composer , deberías echarle un vistazo a League/Csv según tus necesidades. League/Csv tiene una muy buena API para construir archivos CSV .

Para utilizar League/Csv con este método de creación de archivos CSV, consulte este ejemplo


Para dar seguimiento a esto:

Parece que el problema es simplemente con Excel en la Mac. No es como estoy generando los archivos, porque incluso la generación de CSV de Excel los está rompiendo. Guardo como CSV y reimporte, y todos los personajes están en mal estado.

Entonces ... no parece haber una respuesta correcta a esto. Gracias por todas las sugerencias.

Diría que, por todo lo que he leído, la sugerencia de @Daniel Magliola sobre la lista de materiales probablemente sea la mejor respuesta para alguna otra computadora. Pero aún no resuelve mi problema.


Para mí, ninguna de las soluciones anteriores funcionó. A continuación se muestra lo que hice para resolver el problema: modifique el valor usando esta función en el código PHP:

$value = utf8_encode($value);

Este resultado se valora correctamente en una hoja de Excel.


Puede agregar los 3 bytes al archivo antes de exportar, me funciona. Antes de hacer ese sistema solo funcionaba en Windows y HP -UX pero fallaba en Linux.

FileOutputStream fStream = new FileOutputStream( f ); final byte[] bom = new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }; OutputStreamWriter writer = new OutputStreamWriter( fStream, "UTF8" ); fStream.write( bom );

Tener una BOM UTF-8 (3 bytes, hexadecimal EF BB BF) al comienzo del archivo. De lo contrario, Excel interpretará los datos de acuerdo con la codificación predeterminada de su configuración regional (por ejemplo, cp1252) en lugar de utf-8.

Generar archivo CSV para Excel, cómo tener una nueva línea dentro de un valor


Solución EASY para Mac Excel 2008: Luché con esto tantas veces, pero esta fue mi solución: Abra el archivo .csv en Textwrangler, que debería abrir correctamente sus caracteres UTF-8. Ahora, en la barra de estado inferior, cambie el formato de archivo de "Unicode (UTF-8)" a "Western (ISO Latin 1)" y guarde el archivo. Ahora vaya a su Mac Excel 2008 y seleccione Archivo> Importar> Seleccionar csv> Buscar su archivo> en Origen de archivo seleccione "Windows (ANSI)" y verá que los caracteres UTF-8 se muestran correctamente. Por lo menos lo hace por mí...


Tengo el mismo problema (o similar).

En mi caso, si agrego una lista de materiales a la salida, funciona:

header(''Content-Encoding: UTF-8''); header(''Content-type: text/csv; charset=UTF-8''); header(''Content-Disposition: attachment; filename=Customers_Export.csv''); echo "/xEF/xBB/xBF"; // UTF-8 BOM

Creo que este es un truco bastante feo, pero funcionó para mí, al menos para Excel 2007 Windows. No estoy seguro de que funcione en Mac.


Tienes que usar la codificación "Windows-1252".

header(''Content-Encoding: Windows-1252''); header(''Content-type: text/csv; charset=Windows-1252''); header("Content-Disposition: attachment; filename={$filename}");

Tal vez tengas que convertir tus cadenas:

private function convertToWindowsCharset($string) { $encoding = mb_detect_encoding($string); return iconv($encoding, "Windows-1252", $string); }


Tuve el mismo problema cuando tenía una rutina de Excel VBA que importaba datos. Como CSV es un formato de texto sin formato, estaba trabajando en esto al abrir programáticamente los datos en un editor de archivos simple como el Wordpad y volver a guardarlos como texto unicode, o copiarlos al portapapeles desde allí y pegarlos en Excel. Si Excel no analiza automáticamente el CSV en las celdas, esto se remedia fácilmente usando la función integrada "Texto a columnas".


Yo uso esto y funciona

header(''Content-Description: File Transfer''); header(''Content-Type: text/csv; charset=UTF-16LE''); header(''Content-Disposition: attachment; filename=file.csv''); header(''Content-Transfer-Encoding: binary''); header(''Expires: 0''); header(''Cache-Control: must-revalidate, post-check=0, pre-check=0''); header(''Pragma: public''); // output headers so that the file is downloaded rather than displayed // create a file pointer connected to the output stream $output = fopen(''php://output'', ''w''); fputs( $output, "/xEF/xBB/xBF" ); // output the column headings fputcsv($output, array(''Thông tin khách hàng đăng ký'')); // fetch the data $setutf8 = "SET NAMES utf8"; $q = $conn->query($setutf8); $setutf8c = "SET character_set_results = ''utf8'', character_set_client = ''utf8'', character_set_connection = ''utf8'', character_set_database = ''utf8'', character_set_server = ''utf8''"; $qc = $conn->query($setutf8c); $setutf9 = "SET CHARACTER SET utf8"; $q1 = $conn->query($setutf9); $setutf7 = "SET COLLATION_CONNECTION = ''utf8_general_ci''"; $q2 = $conn->query($setutf7); $sql = "SELECT id, name, email FROM myguests"; $rows = $conn->query($sql); $arr1= array(); if ($rows->num_rows > 0) { // output data of each row while($row = $rows->fetch_assoc()) { $rcontent = " Name: " . $row["name"]. " - Email: " . $row["email"]; $arr1[]["title"] = $rcontent; } } else { echo "0 results"; } $conn->close(); // loop over the rows, outputting them foreach($arr1 as $result1): fputcsv($output, $result1); endforeach;


puede convertir su Cadena CSV con iconv . por ejemplo:

$csvString = "Möckmühl;in Möckmühl ist die Hölle los/n"; file_put_contents(''path/newTest.csv'',iconv("UTF-8", "ISO-8859-1//TRANSLIT",$csvString) );


#output un CSV UTF-8 en PHP que Excel leerá correctamente.

//Use tab as field separator $sep = "/t"; $eol = "/n"; $fputcsv = count($headings) ? ''"''. implode(''"''.$sep.''"'', $headings).''"''.$eol : '''';


**This is 100% works fine in excel for both Windows7,8,10 and also All Mac OS.** //Fix issues in excel that are not displaying characters containing diacritics, cyrillic letters, Greek letter and currency symbols. function generateCSVFile($filename, $headings, $data) { //Use tab as field separator $newTab = "/t"; $newLine = "/n"; $fputcsv = count($headings) ? ''"''. implode(''"''.$newTab.''"'', $headings).''"''.$newLine : ''''; // Loop over the * to export if (! empty($data)) { foreach($data as $item) { $fputcsv .= ''"''. implode(''"''.$newTab.''"'', $item).''"''.$newLine; } } //Convert CSV to UTF-16 $encoded_csv = mb_convert_encoding($fputcsv, ''UTF-16LE'', ''UTF-8''); // Output CSV-specific headers header(''Set-Cookie: fileDownload=true; path=/''); //This cookie is needed in order to trigger the success window. header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=/"$filename.csv/";" ); header("Content-Transfer-Encoding: binary"); header(''Content-Length: ''. strlen($encoded_csv)); echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/excel exit; }


//convert UTF-8 file without BOM to UTF-16LE for excel on mac $fileUtf8String = file_get_contents("file.ext"); file_put_contents("file.ext", "/xFF/xFE" . mb_convert_encoding($fileUtf8String, "UTF-16LE", "UTF-8"));