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

191

Tengo esta cosa muy simple que solo muestra algunas cosas en formato CSV, pero tiene que ser UTF-8. Abro 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 tontas. 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 que pueda "abrir como UTF-8" ni nada, así que ... me estoy molestando un poco.

Parece que no puedo encontrar ninguna solución clara para esto en ningún lado, a pesar de que muchas personas tienen el mismo problema. Lo que más veo es incluir la lista de materiales, pero no puedo entender exactamente cómo hacerlo. Como puede ver arriba, solo estoy echoingresando estos datos, no estoy escribiendo ningún archivo. Puedo hacerlo si lo necesito, simplemente no lo soy porque no parece que sea necesario en este momento. ¿Alguna ayuda?

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

Ben Saufley
fuente
2
¿Excel no proporciona una opción para ajustar el conjunto de caracteres del archivo entrante? ¿Estás 100% seguro de eso? No tengo una copia a mano, así que no puedo probar, pero imagino que debe haber un cuadro desplegable en alguna parte.
Pekka
Esto es Excel en una Mac, parece más limitado que Excel en la PC. No hay menús desplegables en absoluto en el cuadro de diálogo Abrir, más allá de qué tipos de archivos se pueden abrir. He buscado por todas partes. Si está allí, es oscuro. Yo diría que 98% seguro.
Ben Saufley, el
Microsoft Office u oficina abierta?
ajreal
Microsoft es mejor en este aspecto, no hay forma (que he encontrado) de hacer que OpenOffice detecte el juego de caracteres, ni siquiera la lista de materiales. Maldita sea.
Ciantic
BOM tampoco tiene ningún efecto en Microsoft Excel 2008 para Mac.
Ben Saufley

Respuestas:

134

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 anteriores a Office 2016 . Las versiones más recientes (de Office 365) ahora admiten UTF-8.

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

  1. Asegúrese de convertir su texto CST 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 al inicio del archivo

    chr(255) . chr(254)

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

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

Usé esta función de los comentarios de PHP (usando las 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 como 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 hojas de cálculo como OpenOffice Calc, los propios números de Apple y la hoja de cálculo de Google Doc no tienen problemas con los archivos UTF-8 con comas.

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


Como nota al margen, podría agregar que si está utilizando Composer , debería echar un vistazo a las necesidades League\Csv. League\Csvtiene una API realmente buena para construir archivos CSV .

Para usar League\Csvcon este método de creación de archivos CSV, consulte este ejemplo

Tim Groeneveld
fuente
1
Llámame estúpido, pero no puedo hacer que esto funcione. Convertí mis datos usando la función mb_convert_encoding y saqué la lista de materiales que precede al contenido del archivo, pero solo obtengo una sola fila de caracteres chinos cuando abro el archivo en Excel. Todavía estoy usando comas en lugar de pestañas por ahora, pero presumiblemente eso no debería causar lo que estoy viendo.
John Rix
@JohnRix eso es extraño. Este código literalmente ha resuelto todos los problemas que he tenido con los archivos CSV que se exportan, con la excepción de los importadores que solo aceptan comas. ¿Puede enviarme un pastebin del código que está utilizando, junto con una matriz que está convirtiendo en un CSV y una copia del archivo exportado?
Tim Groeneveld
2
Esta solución también resolvió el problema de UTF8 para mí en Mac y Windows. También descubrí que agregar una línea con sep=;o sep=,al archivo CSV le dice a Excel cómo se separa el CSV y las columnas se crearán correctamente nuevamente.
Luc Wollants el
55
Descubrí que las cosas salían confusas si comencé la cadena como solo la lista de materiales, luego en otra línea agregué el "sep=,\n", luego en otra línea agregué los datos. Las cosas estaban bien si lo hacía todo en una línea ( $csv = chr(255) . chr(254) /* BOM */ . "sep=,\n" . mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');). Todo se ve muy bien ahora en Mac. No tengo Windows para probar.
temblor
2
Lo único que funcionó completamente para mí. La inconsistencia de Microsoft nunca deja de sorprenderme. Guardar un archivo csv normal usa "," como delimitador, pero si hay una lista de materiales, se guarda usando "\ t" por alguna razón. La C en .csv significa "COMMA" maldita sea. Realmente no es difícil de hacer.
Phil
288

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.

Daniel Magliola
fuente
10
Feo, pero muy servicial. Gracias.
abelito
77
Estoy bastante seguro de que esto no funciona bien en OS X, desafortunadamente. Creo que en realidad podría mostrar la lista de materiales al importar: (advertencia recuerdos nebulosos.)
davidtbernal
2
Esto es correcto. Al menos, he intentado pretender con una lista de materiales, como en el ejemplo anterior, pero de hecho solo mostró algunos caracteres originales al principio y seguí mostrando los caracteres especiales mal (probado en Excel 2011). Esto pareció funcionar mejor para mí en todas las configuraciones: stackoverflow.com/a/1648671/1005334 (usando PHP).
kasimir
44
Sigo recibiendo alertas sobre esta pregunta porque aparentemente muchas otras personas se topan con ella. Desearía poder marcar esto como correcto, porque se ha votado mucho. Desafortunadamente, finalmente le di una oportunidad a esta solución (abandoné ese proyecto hace mucho tiempo) y no me funciona en Excel 2008 para Mac. Me alegra que te esté funcionando. He votado a favor de la solución. Pero no resuelve el problema de Excel para Mac 2008. Si alguien tiene suerte en la Mac, definitivamente házmelo saber (y aparentemente a todos ).
Ben Saufley
Funciona maravillosamente enviando un archivo CSV a MS Excel Starter 2010. ¡Muchas gracias!
Jamie Dexter
32

Así es como lo hice (para solicitar al navegador que 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 presionó la barra espaciadora en Mac ... pero no en Excel Mac 2008 ... no sé por qué

Jazzer
fuente
1
La línea UTF-8 BOM del código me salvó el día exportando a xls
Mladen Janjetovic
66
Estaba buscando una forma de enviar directamente al navegador como utf8, cuando me encontré con esta publicación, aquí está mi solución con créditos para esta publicación para la lista de materiales y el encabezado de transferencia binaria. $outstream = fopen( "php://output", 'w' ); fputs( $outstream, "\xEF\xBB\xBF" ); foreach ( $export as $fields ) { fputcsv( $outstream, $fields ); } fclose( $outstream );
fyrye
Error tipográfico: elimina el doble )).
sitilge
22

Acabo de abordar el mismo problema y se me ocurrieron dos soluciones.

  1. Use la clase PHPExcel como lo sugiere bpeterson76 .

    • El uso de esta clase genera el archivo más ampliamente 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 cual no es un problema para archivos de tamaño razonable, pero si su archivo Excel / CSV tiene cientos o miles de filas, esta biblioteca queda inutilizable .
    • Aquí hay un método PHP que tomará algunos datos de TSV y generará un archivo de Excel en el navegador, tenga en cuenta que usa Excel5 Writer, lo que significa que el archivo debería ser compatible con versiones anteriores de Excel, pero ya no tengo acceso a ninguno, entonces 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 pude encontrar fue un archivo que fuera 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 aquí , específicamente, esta respuesta , pero también debe 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;
Jasdeep Gosal
fuente
Me enfrento al mismo problema en Windows-7 Excel 2007 y probé todas las sugerencias pero fallé :(
PHP Ferrari
La solución UTF-16LE es la que funcionó. Tenga en cuenta que debe formatear el tsv correctamente, y debe ser tsc, por lo tanto, delimitado por tabuladores, no delimitado por comas. Vea también la publicación de Marc aquí: stackoverflow.com/a/1648671/1697370
Ellert van Koperen
16

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();
Reza Mamun
fuente
13

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

mb_convert_encoding($output, 'UCS-2LE', 'UTF-8');
Leopold Gault
fuente
3
Mejor use UTF-16LE como se sugirió anteriormente, que cubre todos los personajes existentes.
Ellert van Koperen
Me di cuenta de que mb_convert_encoding funciona bien y muestra diacríticos correctamente en mi archivo XLS exportado. Tengo configuraciones predeterminadas de mysql y apache + php configurado para funcionar con utf-8
Junior Mayhé
10

En mi caso, a continuación 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 0xBFencabezado BOM le permitirá a Excel conocer la codificación correcta.

Codemole
fuente
1
grande para ti hermano <3
Adrien G
fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));<- esto es exactamente lo que necesitaba. Funciona a las mil maravillas.
Alex
8

Para seguir con esto:

Parece que el problema es simplemente con Excel en la Mac. No es como estoy generando los archivos, porque incluso generar CSV desde Excel está rompiendo. Guardo como CSV y reimporto, 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 de todo lo que he leído, la sugerencia de @Daniel Magliola sobre la lista de materiales probablemente sería la mejor respuesta para alguna otra computadora. Pero todavía no resuelve mi problema.

Ben Saufley
fuente
Dado que la compatibilidad con UTF8 es inconsistente en Mac vs Windows, la mejor opción es usar una codificación completamente diferente. He encontrado que cp1252 generalmente juega bien con cosas de Microsoft. en.wikipedia.org/wiki/Windows-1252
s29
1
Ben, hay una respuesta correcta a esta pregunta :) ¡Mira la mía!
Tim Groeneveld
7

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

Solucione 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;
}
Murali Krishna
fuente
Esta solución me permitió hacer que la exportación funcionara también para Google Sheets (algunas otras fallaron)
Cafn
6

El archivo CSV debe incluir una marca de orden de bytes.

O como se sugiere y la solución alternativa, simplemente repítalo con el cuerpo HTTP

Cybot
fuente
4

Dado que la codificación UTF8 no funciona bien con Excel. Puede convertir los datos a otro tipo de codificación utilizandoiconv() .

p.ej

iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),
Abrar A. Shareef
fuente
Esta fue la única solución que funcionó para mí con Excel Mac 2011
Christer Fernstrom
4

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);
Rejaul
fuente
3

La conversión de texto codificado ya utf-8 mediante el uso mb_convert_encodingno es necesaria. Simplemente agregue tres caracteres delante 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.

Rvanlaak
fuente
Increíble; Intenté al menos otras 10 soluciones y la única solución para mí parece ser esta, cuando se combina con UTF-8 BOM a través de fputs.
kaarto
2

Mientras investigaba y descubrí que UTF-8 no funciona bien en MAC y Windows, intenté con Windows-1252, es compatible con ambos, pero debe seleccionar el tipo de codificación en ubuntu. Aqui esta mi codigo$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
Ho Ha
fuente
2
**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;
}
Sagar72427
fuente
2
En general, las respuestas son mucho más útiles si incluyen una explicación de lo que el código pretende hacer y por qué eso resuelve el problema sin introducir otros.
Tim Diekmann
1

¿Qué tal solo generar para Excel en sí? Esta es una clase excelente que le permite generar archivos XLS del lado del servidor. Lo uso con frecuencia para clientes que no pueden "descifrar" los csv y hasta ahora nunca han tenido una queja. También permite un formato adicional (sombreado, alturas de fila, cálculos, etc.) que csv nunca hará.

bpeterson76
fuente
Tenga en cuenta que phpexcel tiene problemas con grandes cantidades de datos.
Ellert van Koperen
1

puedes convertir tu 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) );
foued611
fuente
Grandes textos de muestra;)
ngeek
1

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}");

Quizás tengas que convertir tus cadenas:

private function convertToWindowsCharset($string) {
  $encoding = mb_detect_encoding($string);

  return iconv($encoding, "Windows-1252", $string);
}
roNn23
fuente
1

Puede agregar los 3 bytes al archivo antes de exportar, funciona para mí. 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 lista de materiales 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 localidad (por ejemplo, cp1252) en lugar de utf-8

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

Cherry Yap
fuente
1

Estoy en Mac, en mi caso solo tuve que especificar el separador "sep=;\n"y codificar el archivo en UTF-16LE de esta manera:

$data = "sep=;\n" .mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');
Sebastien Horin
fuente
1

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

$value = utf8_encode($value);

Esta salida se valora correctamente en una hoja de Excel.

Barani r
fuente
0

Tuve el mismo problema cuando tuve una rutina Excel VBA que importaba datos. Como CSV es un formato de texto plano, estaba trabajando en esto abriendo programáticamente los datos en un editor de archivos simple como wordpad, y volviéndolos a guardar como texto unicode, o copiándolos en el portapapeles desde allí y pegándolos en Excel. Si Excel no analiza automáticamente el CSV en las celdas, esto se soluciona fácilmente utilizando la función integrada "Texto a columnas".

Alain
fuente
¡Lo he intentado! Pero ya está codificado como texto unicode ... guardarlo como texto unicode no cambia nada. ¿Cómo lo guardaría como texto plano sin que interprete incorrectamente todos los caracteres especiales?
Ben Saufley, el
Creo que al "guardarlo como texto Unicode", Alain podría significar "UTF-16LE". Windows a menudo (lamentablemente) usa "Unicode" para referirse incorrectamente a UTF-16LE o UTF-16LE con una lista de materiales principal. Archivo del Bloc de notas -> Guardar cuadro de diálogo utiliza "Unicode" de esta manera.
Thanatos
0

¿Sigue ocurriendo el problema cuando lo guarda como un archivo .txt y lo abren 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.

Alain
fuente
Que yo sepa, el formato CSV está bien. Puedo hacer un CSV "perfecto" en TextEdit, no hay problema, o incluso cambiar el nombre de un txt como csv, para que no falte nada secreto: los CSV son solo archivos de texto. Además, el formato es perfecto en Excel, son solo los caracteres especiales los que se rompen. Pero por si acaso, probé su sugerencia, y lamentablemente está produciendo los mismos problemas.
Ben Saufley, el
Desde el departamento "WTF estaban pensando": tenga en cuenta que, según Microsoft, el separador de campo correcto depende de la configuración regional. Un archivo 'separado por comas' podría requerir que los campos estén realmente separados por punto y coma en algunas configuraciones regionales, y no hay nada que pueda hacer excepto sugerir OpenOffice
djn
eso es bastante loco, desafortunadamente no tengo problemas para delimitar los campos correctamente. Solo estoy teniendo problemas con estos personajes especiales.
Ben Saufley
0

Esta publicación es bastante antigua, pero después de horas de intentarlo quiero compartir mi solución ... tal vez ayude a alguien a lidiar 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 iconv´s pero no pude lograr que las diéresis alemanas funcionaran en Mac Excel 2004. Una solución: PHPExcel. Es genial, pero para mi proyecto es 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 las diéresis alemanas excel (ä, ö, Ü, ...).

t libro
fuente
0

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

    encabezado ('Codificación de contenido: UTF-8');
    header ('Tipo de contenido: text / csv; charset = UTF-8');
    header ("Contenido-disposición: archivo adjunto; filename = filename.csv");
    encabezado ("Pragma: público");
    encabezado ("Caduca: 0");
    echo "\ xEF \ xBB \ xBF"; // BOM UTF-8

Brian
fuente
Sí, eso es correcto, funcionará correctamente en Excel para Windows, pero como se explicó en mi respuesta, no funcionará en Excel para OS X.
Tim Groeneveld
0

De lo contrario, 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);
usuario3519396
fuente
0

Solución FÁCIL para Mac Excel 2008: luché con esto muchas veces, pero aquí estaba mi solución fácil: abra el archivo .csv en Textwrangler que debería abrir sus caracteres UTF-8 correctamente. 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 del archivo, seleccione "Windows (ANSI)" y listo, los caracteres UTF-8 se muestran correctamente. Por lo menos lo hace por mí...

Poul
fuente
0

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;
BoRnbeBaD
fuente
0

# Salga 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 : '';
Murali Krishna
fuente
Una respuesta por persona es suficiente. En el futuro, recuerde que puede agregar información a su respuesta en cualquier momento, no necesita crear 2
RiggsFolly
-1
//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"));
b3wii
fuente
Esta pregunta no pregunta cómo convertir, sino cómo generar resultados. La parte relevante de esta contribución, que sale en UTF-16, ya está contribuida en la Respuesta Seleccionada .
Ben Saufley
@BenSaufley Bueno, pero resuelve el problema de la pregunta con 2 líneas simples de código
b3wii
La pregunta ya está resuelta, y también se explica más a fondo.
Ben Saufley