it-swarm.com.de

Wie kann ich ein UTF-8 CSV in ausgeben PHP dass Excel richtig lesen wird?

Ich habe diese sehr einfache Sache, die nur etwas im CSV-Format ausgibt, aber es muss UTF-8 sein. Ich öffne diese Datei in TextEdit oder TextMate oder Dreamweaver und zeigt UTF-8-Zeichen ordnungsgemäß an. Wenn ich sie jedoch in Excel öffne, macht sie diese dumme, ätherische Sache. Folgendes habe ich an der Spitze meines Dokuments:

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

All dies scheint den gewünschten Effekt zu haben, außer dass Excel (Mac 2008) es nicht richtig importieren möchte. In Excel gibt es keine Optionen für das "Öffnen als UTF-8" oder so, also ... Ich werde etwas verärgert.

Ich kann scheinbar keine klare Lösung dafür finden, obwohl viele Leute das gleiche Problem haben. Am meisten sehe ich die Stückliste, aber ich kann nicht genau herausfinden, wie das geht. Wie Sie oben sehen können, bin ich nur echoing, und ich schreibe keine Dateien. Ich kann das tun, wenn ich muss, ich bin einfach nicht, weil es zu diesem Zeitpunkt nicht so aussieht, als wäre es notwendig. Irgendeine Hilfe?

Update: Ich habe versucht, die Stückliste als echo pack("CCC", 0xef, 0xbb, 0xbf); zu wiederholen, die ich gerade von einer Site gezogen habe, die versucht hat, die Stückliste zu erkennen. Excel fügt diese drei Zeichen beim Importieren jedoch nur an die erste Zelle an und führt die Sonderzeichen trotzdem durcheinander.

167
Ben Saufley

Um einen Microsoft-Supporttechniker zu zitieren,

Derzeit unterstützt Excel für Mac kein UTF-8

Update, 2017: Dies gilt für alle Versionen von Microsoft Excel für Mac vor Office 2016. Neuere Versionen (von Office 365) unterstützen jetzt UTF-8.

Um UTF-8-Inhalte auszugeben, die Excel sowohl unter Windows als auch unter OS X erfolgreich lesen kann, müssen Sie zwei Schritte ausführen:

  1. Stellen Sie sicher, dass Sie Ihren UTF-8-Text in UTF-16LE konvertieren

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
  2. Stellen Sie sicher, dass Sie die UTF-16LE-Byte-Bestellmarke hinzufügen

    chr(255) . chr(254)
    

Das nächste Problem, das nur in Excel unter OS X auftritt (aber nicht Windows), wird beim Anzeigen einer CSV-Datei mit durch Kommas getrennten Werten angezeigt. Excel rendert Zeilen nur mit einer Zeile und dem gesamten Text zusammen mit den Kommas die erste Reihe.

Um dies zu vermeiden, verwenden Sie Tabulatoren als getrennten Wert.

Ich habe diese Funktion aus den PHP -Kommentaren (unter Verwendung der Tabs "\ t" anstelle von Kommas) verwendet und es hat perfekt auf OS X und Windows Excel funktioniert.

Beachten Sie Folgendes, um ein Problem mit einer leeren Spalte am Ende einer Zeile zu beheben, musste ich die folgende Codezeile ändern:

    $field_cnt = count($fields);

zu

    $field_cnt = count($fields)-1;

Wie in anderen Kommentaren auf dieser Seite bereits vermerkt ist, haben andere Tabellenkalkulationsprogramme wie OpenOffice Calc, Apples eigene Zahlen und Google Docs Spreadsheet keine Probleme mit UTF-8-Dateien mit Kommas.

Siehe die Tabelle in dieser Frage , was für Unicode CSV-Dateien in Excel funktioniert und nicht funktioniert


Als Randbemerkung kann ich hinzufügen, dass Sie, wenn Sie Composer verwenden, einen Blick auf das Hinzufügen von League\Csv zu Ihren Anforderungen werfen sollten. League\Csv hat eine wirklich schöne API zum Erstellen von CSV-Dateien .

Um League\Csv mit dieser Methode zum Erstellen von CSV-Dateien zu verwenden, checken Sie dieses Beispiel aus.

119
Tim Groeneveld

Ich habe das gleiche (oder ähnliche) Problem.

Wenn ich der Ausgabe eine Stückliste hinzufüge, funktioniert es in meinem Fall:

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

Ich glaube, das ist ein ziemlich hässlicher Hack, aber es funktionierte für mich, zumindest für Excel 2007 Windows. Nicht sicher, ob es auf Mac funktioniert.

258
Daniel Magliola

So habe ich es gemacht (das ist der Prompt-Browser, um die CSV-Datei herunterzuladen):

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();

Das einzige Problem, das UTF8-Codierungsproblem in der CSV-Vorschau behoben hat, wenn Sie die Leertaste auf dem Mac drücken

30
Jazzer

Ich habe mich gerade mit dem gleichen Problem befasst und zwei Lösungen gefunden. 

  1. Verwenden Sie die PHPExcel class wie von bpeterson76 vorgeschlagen. 

    • Mit dieser Klasse wurde die am weitesten kompatible Datei generiert. Ich konnte eine Datei aus UTF-8-kodierten Daten generieren, die in Excel 2008 Mac, Excel 2007 Windows und Google Docs einwandfrei geöffnet wurden. 
    • Das größte Problem bei der Verwendung von PHPExcel ist, dass es langsam ist und viel Speicher verwendet. Dies ist bei Dateien mit angemessener Größe kein Problem, aber wenn Ihre Excel/CSV-Datei Hunderte oder Tausende von Zeilen enthält, wird diese Bibliothek unbrauchbar.
    • Hier ist eine PHP Methode, die einige TSV-Daten übernimmt und eine Excel-Datei an den Browser ausgibt. Beachten Sie, dass sie den Excel5 Writer verwendet, was bedeutet, dass die Datei mit älteren Versionen von Excel kompatibel sein sollte, ich aber keine habe länger Zugriff auf alle, so dass ich sie nicht testen kann. 

      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. Wegen der Effizienzprobleme bei PHPExcel musste ich auch herausfinden, wie eine UTF-8 & Excel-kompatible CSV- oder TSV-Datei erstellt wird. 

    • Das Beste, was ich finden konnte, war eine Datei, die mit Excel 2008 Mac und Excel 2007 PC kompatibel war, nicht jedoch mit Google Docs, was für meine Anwendung gut genug ist. 
    • Ich habe die Lösung hier speziell diese Antwort gefunden , aber Sie sollten auch die akzeptierte Antwort lesen wie sie das Problem erklärt. 
    • Hier ist der PHP Code, den ich verwendet habe. Beachten Sie, dass ich TSV-Daten (Tabulatoren als Trennzeichen anstelle von Kommas) verwende: 

      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;
      
22
Jasdeep Gosal

Ich hatte das gleiche Problem und es wurde wie folgt gelöst:

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

UTF-8 wird von Excel nicht unterstützt. Sie müssen Ihren UTF-8-Text in UCS-2LE codieren.

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

Um dies zu verfolgen:

Es scheint, dass das Problem einfach mit Excel auf dem Mac liegt. Es ist nicht so, wie ich die Dateien generiere, denn sogar das Generieren von CSVs aus Excel zerstört sie. Ich speichere als CSV und importiere erneut, und alle Charaktere sind durcheinander.

Es scheint also keine richtige Antwort darauf zu geben. Danke für alle Vorschläge.

Ich würde sagen, dass @Daniel Magliolas Vorschlag zur Stückliste wahrscheinlich die beste Antwort für einen anderen Computer ist. Aber es löst immer noch nicht mein Problem.

8
Ben Saufley

Dies funktioniert in Excel sowohl für Windows als auch für Mac OS.

Beheben Sie Probleme in Excel, die keine Zeichen anzeigen, die diakritische Zeichen, kyrillische Buchstaben, griechische Buchstaben und Währungssymbole enthalten.

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;
}
6
Murali Krishna

Die CSV-Datei muss eine Byte Order Mark enthalten.

Oder wie vorgeschlagen und Abhilfe einfach mit dem HTTP-Body wiederholen

6
Cybot

In meinem Fall funktioniert das folgende sehr schön, um CSV-Dateien mit UTF-8-Zeichen korrekt in Excel anzuzeigen.

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

Der 0xEF 0xBB 0xBF BOM-Header teilt Excel die korrekte Kodierung mit.

5
Codemole

Da UTF8-Kodierung mit Excel nicht gut funktioniert. Sie können die Daten mit iconv() in einen anderen Codierungstyp konvertieren.

z.B.

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

Hinzufügen:

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

Oder:

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

Bevor Sie Inhalte in eine CSV-Datei schreiben.

Beispiel:

<?php
$file = fopen( "file.csv", "w");
fprintf( $file, "\xEF\xBB\xBF");
fputcsv( $file, ["english", 122, "বাংলা"]);
fclose($file);
4
Rejaul
**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;
}
2
Sagar72427

Als ich nachforschte und herausfand, dass UTF-8 auf MAC und Windows nicht gut funktioniert, versuchte ich es mit Windows-1252, es unterstützt beide gut, aber Sie müssen die Art der Kodierung auf Ubuntu auswählen. Hier ist mein Code$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
2
Ho Ha

Für mich hat keine der oben genannten Lösungen funktioniert. Im Folgenden habe ich das Problem behoben: Ändern Sie den Wert mithilfe dieser Funktion im Code PHP: 

$value = utf8_encode($value);

Diese Werte werden korrekt in einer Excel-Tabelle ausgegeben. 

1
Barani r

Sie müssen die Kodierung "Windows-1252" verwenden. 

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

Vielleicht müssen Sie Ihre Zeichenketten konvertieren:

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

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

Wie wäre es nur für Excel selbst auszugeben? Dies ist eine hervorragende Klasse , mit der Sie serverseitig XLS-Dateien generieren können. Ich benutze es häufig für Kunden, die CSVs nicht "herausfinden" können und bisher nie eine Beschwerde hatten. Es erlaubt auch einige zusätzliche Formatierungen (Schattierungen, Zeilenhöhen, Berechnungen usw.), die csv niemals ausführen wird. 

1
bpeterson76

sie können Ihren CSV-String mit iconv ..__ konvertieren. zum Beispiel:

$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) );
1
foued611

Das Konvertieren von bereits mit Utf-8 codiertem Text mithilfe von mb_convert_encoding ist nicht erforderlich. Fügen Sie einfach drei Zeichen vor dem ursprünglichen Inhalt hinzu:

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

Für mich wurde das Problem der Sonderzeichen in CSV-Dateien behoben.

1
Rvanlaak

Ich bin auf einem Mac, in meinem Fall musste ich lediglich das Trennzeichen mit "sep=;\n" angeben und die Datei in UTF-16LE wie folgt codieren:

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

# gibt einen UTF-8-CSV in PHP aus, den Excel ordnungsgemäß lesen wird.

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

Ich benutze das und es funktioniert 

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

EASY-Lösung für Mac Excel 2008: Ich habe oft mit diesem Problem zu kämpfen gehabt, aber hier war meine einfache Lösung: Öffnen Sie die CSV-Datei in Textwrangler, die Ihre UTF-8-Zeichen korrekt öffnen sollte. Ändern Sie nun in der unteren Statusleiste das Dateiformat von "Unicode (UTF-8)" in "Western (ISO Latin 1)" und speichern Sie die Datei . Gehen Sie zu Ihrem Mac Excel 2008 und wählen Sie "Datei"> "Importieren"> "Auswählen" csv> Finden Sie Ihre Datei> Wählen Sie in File Origin "Windows (ANSI)" aus, und die UTF-8-Zeichen werden korrekt angezeigt. Zumindest tut es für mich ...

0
Poul

Ich hatte das gleiche Problem, als ich eine Excel VBA-Routine hatte, die Daten importierte. Da es sich bei CSV um ein Nur-Text-Format handelt, habe ich das Problem gelöst, indem ich die Daten programmatisch in einem einfachen Datei-Editor wie Wordpad geöffnet und als Unicode-Text gespeichert habe oder von dort in die Zwischenablage kopiert und in Excel eingefügt habe. Wenn Excel die CSV nicht automatisch in Zellen parst, lässt sich dies leicht mit der integrierten Funktion "Text in Spalten" beheben.

0
Alain

Ich habe diese Kopfzeilen gerade ausprobiert und Excel 2013 auf einem Windows 7-PC zum Importieren der CSV-Datei mit Sonderzeichen verwendet. Die Byte Order Mark (BOM) war der letzte Schlüssel, der es funktionierte.

 Header ('Content-Encoding: UTF-8'); 
 header ('Inhaltstyp: text/csv; Zeichensatz = UTF-8'); 
 Header ("Content-Disposition: Anhang; Dateiname = Dateiname.csv"); 
 header ("Pragma: public"); 
 header ("Expires: 0"); 
 echo "\ xEF\xBB\xBF"; // UTF-8-Stückliste 

0
Brian

Ansonsten können Sie:

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);
0
user3519396

Tritt das Problem weiterhin auf, wenn Sie es als TXT-Datei speichern und diese in Excel mit Komma als Trennzeichen öffnen?

Das Problem liegt möglicherweise nicht in der Kodierung, sondern es kann auch sein, dass die Datei nach Excel-Standards keine perfekte CSV ist.

0
Alain

Sie können die 3 Bytes vor dem Exportieren an die Datei anhängen, das funktioniert für mich. Bevor dieses System funktioniert, funktioniert das System nur unter Windows und HP -UX, ist aber unter Linux fehlgeschlagen.

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

Habe am Anfang der Datei eine UTF-8-Stückliste (3 Byte, hex EF BB BF). Andernfalls interpretiert Excel die Daten gemäß der Standardcodierung Ihres Gebietsschemas (z. B. cp1252) anstelle von utf-8 

CSV-Datei für Excel erstellen, Zeilenumbrüche in einem Wert enthalten

0
Cherry Yap

Dieser Beitrag ist ziemlich alt, aber nach stundenlangen Versuchen möchte ich meine Lösung mitteilen. Vielleicht hilft er jemandem, der sich mit Excel, Mac und CSV beschäftigt, und stolpert über diese Bedrohung. Ich generiere eine csv dynamisch als Ausgabe aus einer Datenbank mit Blick auf Excel-Benutzer. (UTF-8 mit Stückliste)

Ich habe viele iconv´s ausprobiert, konnte aber keine deutschen Umlaute in Mac Excel 2004 verwenden. Eine Lösung: PHPExcel. Es ist toll, aber für mein Projekt ein bisschen zu viel. Was für mich funktioniert, ist das Erstellen der csv-Datei und das Konvertieren dieser csv-Datei in xls mit diesem PHPsnippet: csv2xls . Das Ergebnis xls funktioniert mit Excel-Umlauten (ä, ö, Ü, ...).

0
t Book