it-swarm.com.de

Microsoft Excel mangelt diakritische Zeichen in CSV-Dateien?

Ich exportiere programmgesteuert Daten (mit PHP 5.2)) in eine CSV-Testdatei.
Beispieldaten: Numéro 1 (Akzent e beachten). Die Daten sind utf-8 (Keine vorangestellte Stückliste).

Wenn ich diese Datei in MS Excel öffne, wird sie als Numéro 1 Angezeigt.

Ich kann dies in einem Texteditor (UltraEdit) öffnen, der es korrekt anzeigt. UE meldet, dass das Zeichen decimal 233 Ist.

Wie kann ich Text exportieren Daten in einer CSV-Datei so dass MS Excel korrekt rendert es, vorzugsweise ohne die Verwendung des Import-Assistenten oder nicht standardmäßige Assistenteneinstellungen zu erzwingen ?

184
Freddo411

Eine korrekt formatierte UTF8-Datei kann als erste drei Oktette ein Byte Order Mark haben. Dies sind die Hex-Werte 0xEF, 0xBB, 0xBF. Diese Oktette dienen dazu, die Datei als UTF8 zu kennzeichnen (da sie nicht als "Bytereihenfolge" -Information relevant sind). 1 Wenn diese Stückliste nicht vorhanden ist, kann der Verbraucher/Leser auf die Codierungsart von schließen der Text. Leser, die nicht UTF8-fähig sind, lesen die Bytes wie eine andere Codierung, z. B. Windows-1252, und zeigen die Zeichen  Am Anfang der Datei an.

Es ist ein Fehler bekannt, bei dem Excel beim Öffnen von UTF8-CSV-Dateien über die Dateizuordnung davon ausgeht, dass sie sich in einer Einzelbytecodierung befinden , wobei das Vorhandensein von ignoriert wird die UTF8-Stückliste. Dies kann nicht durch eine Systemstandard-Codepage oder Spracheinstellung behoben werden. Die Stückliste wird in Excel nicht angezeigt - es wird einfach nicht funktionieren. (Ein Minderheitsbericht behauptet, dass die Stückliste manchmal den Assistenten "Text importieren" auslöst.) Dieser Fehler scheint in Excel 2003 und früheren Versionen vorhanden zu sein. Die meisten Berichte (inmitten der Antworten hier) besagen, dass dies in Excel 2007 und höher behoben ist.

Beachten Sie, dass Sie UTF8-CSV-Dateien in Excel immer * korrekt öffnen können , indem Sie den Assistenten "Text importieren" verwenden, mit dem Sie die Codierung der von Ihnen ausgewählten Datei festlegen können öffnen sich. Das ist natürlich viel unbequemer.

Leser dieser Antwort werden höchstwahrscheinlich nicht in der Lage sein, Excel <2007 besonders zu unterstützen, sondern unformatierten UTF8-Text an Excel zu senden, der falsch interpretiert wird und Ihren Text mit à Und anderen ähnlichen Windows- 1252 Zeichen. Das Hinzufügen der UTF8-Stückliste ist wahrscheinlich die beste und schnellste Lösung.

Wenn Sie mit älteren Excels-Benutzern nicht weiterkommen und Excel der einzige Consumer Ihrer CSVs ist, können Sie dies umgehen, indem Sie UTF16 anstelle von UTF8 exportieren. In Excel 2000 und 2003 werden diese korrekt per Doppelklick geöffnet. (Einige andere Texteditoren können Probleme mit UTF16 haben, daher müssen Sie Ihre Optionen möglicherweise sorgfältig abwägen.)


* Mit Ausnahme der Fälle, in denen dies nicht möglich ist, funktioniert Excel 2011 für Mac-Import Wizard nicht immer mit allen Codierungen, unabhängig davon, was Sie angeben. </ anecdotal-evidence> :)

232
James Baker

Das Voranstellen einer Stückliste (\ uFEFF) hat bei mir funktioniert (Excel 2007), in dem Excel die Datei als UTF-8 erkannt hat. Andernfalls funktioniert das Speichern und Verwenden des Importassistenten, ist jedoch weniger ideal.

38
Fergal

Unten ist der PHP Code, den ich in meinem Projekt verwende, wenn ich Microsoft Excel an den Benutzer sende:

  /**
   * Export an array as downladable Excel CSV
   * @param array   $header
   * @param array   $data
   * @param string  $filename
   */
  function toCSV($header, $data, $filename) {
    $sep  = "\t";
    $eol  = "\n";
    $csv  =  count($header) ? '"'. implode('"'.$sep.'"', $header).'"'.$eol : '';
    foreach($data as $line) {
      $csv .= '"'. implode('"'.$sep.'"', $line).'"'.$eol;
    }
    $encoded_csv = mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    header('Content-Description: File Transfer');
    header('Content-Type: application/vnd.ms-Excel');
    header('Content-Disposition: attachment; filename="'.$filename.'.csv"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv;
    exit;
  }

AKTUALISIERT: Verbesserung des Dateinamens und Fehlerbehebung bei der Berechnung der korrekten Länge. Vielen Dank an TRiG und @ ivanhoe011

30
Marc Carlucci

Die Antwort für alle Kombinationen von Excel-Versionen (2003 + 2007) und Dateitypen

Die meisten anderen Antworten hier beziehen sich nur auf die Excel-Version und werden Ihnen nicht unbedingt weiterhelfen, da ihre Antwort für Ihre Excel-Version möglicherweise nicht zutrifft.

Das Hinzufügen des Stücklistenzeichens führt beispielsweise zu Problemen bei der automatischen Erkennung von Spaltentrennzeichen, jedoch nicht bei jeder Excel-Version.

Es gibt 3 Variablen, die bestimmen, ob es in den meisten Excel-Versionen funktioniert:

  • Codierung
  • BOM-Zeichen vorhanden
  • Zellentrenner

Jemand, der bei SAP stoisch ist, hat jede Kombination ausprobiert und das Ergebnis gemeldet. Endresultat? Verwenden Sie UTF16le mit Stückliste und Tabulatorzeichen als Trennzeichen, damit es in den meisten Excel-Versionen funktioniert.

Du glaubst mir nicht? Ich würde auch nicht, aber hier lesen und weinen: http://wiki.sdn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator

13

Echo UTF-8 Stückliste vor der Ausgabe von CSV-Daten. Dies behebt alle Charakterprobleme in Windows, funktioniert jedoch nicht für Mac.

echo "\xEF\xBB\xBF";

Das funktioniert bei mir, weil ich eine Datei generieren muss, die nur auf Windows-PCs verwendet wird.

8
Johal

UTF-8 funktioniert in Office 2007 nicht ohne Service Pack, mit oder ohne Stückliste (U + ffef oder 0xEF, 0xBB, 0xBF, funktioniert auch nicht). Wenn Sie sp3 installieren, funktioniert UTF-8, wenn 0xEF, 0xBB, 0xBF BOM ist vorangestellt.

UTF-16 funktioniert beim Codieren in python mit "utf-16-le" mit vorangestelltem 0xff 0xef-BOM und mit tab als Trennzeichen. Ich musste die BOM manuell ausschreiben und dann verwenden "utf-16-le" statt "utf-16", andernfalls hat encode () der Stückliste jede Zeile vorangestellt, die als Müll in der ersten Spalte der zweiten Zeile und danach angezeigt wurde.

ich kann nicht sagen, ob UTF-16 ohne installierten SP funktionieren würde, da ich jetzt nicht zurück kann. Seufzer

Dies ist auf Windows, keine Ahnung über Office für MAC.

in beiden Fällen funktioniert der Import, wenn ein Download direkt über den Browser gestartet wird, und der Textimport-Assistent greift nicht ein, wie Sie es erwarten würden.

7
gerald dol

Wie Fregal sagte, ist der Weg zu gehen.

<%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%>
<%
Response.Clear();
Response.ContentType = "text/csv";
Response.Charset = "utf-8";
Response.AddHeader("Content-Disposition", "attachment; filename=excelTest.csv");
Response.Write("\uFEFF");
// csv text here
%>
4

Sie können eine HTML-Datei mit der Erweiterung 'xls' speichern und Akzente setzen (mindestens vor 2007).

Beispiel: Speichern Sie dies (mit Save As utf8 in Notepad) als test.xls:

<html>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8" />
<table>
<tr>
  <th>id</th>
  <th>name</th>
</tr>
<tr>
 <td>4</td>
 <td>Hélène</td>
</tr>
</table>
</html>
2
Benjol

Ich habe auch bemerkt, dass die Frage vor einiger Zeit "beantwortet" wurde, aber ich verstehe die Geschichten nicht, die besagen, dass Sie eine utf8-codierte CSV-Datei nicht erfolgreich in Excel öffnen können, ohne den Textassistenten zu verwenden.

Meine reproduzierbare Erfahrung: Typ Old MacDonald had a farm,ÈÌÉÍØ im Editor drücken Sie die Eingabetaste und dann Speichern unter (mit der UTF-8-Option).

Verwenden Sie Python, um zu zeigen, was tatsächlich darin enthalten ist:

>>> open('oldmac.csv', 'rb').read()
'\xef\xbb\xbfOld MacDonald had a farm,\xc3\x88\xc3\x8c\xc3\x89\xc3\x8d\xc3\x98\r\n'
>>> ^Z

Gut. Notepad hat vorne eine Stückliste angebracht.

Rufen Sie nun den Windows Explorer auf, doppelklicken Sie auf den Dateinamen oder klicken Sie mit der rechten Maustaste und wählen Sie "Öffnen mit ...", um Excel (2003) mit der erwarteten Anzeige zu öffnen.

2
John Machin

Das CSV-Format wird in Excel als ASCII- und nicht als Unicode-Format implementiert, wodurch die diakritischen Zeichen gestört werden. Wir hatten das gleiche Problem: Ich habe festgestellt, dass der offizielle CSV-Standard in Excel als ASCII-basiert definiert wurde.

1
Jeff Yates

In Excel 2007 wird UTF-8 mit BOM (EF BB BF) -codiertem CSV ordnungsgemäß gelesen.

In Excel 2003 (und möglicherweise früher) wird UTF-16LE mit Stückliste (FF FE) gelesen, jedoch mit Tabulatoren anstelle von Kommas oder Semikolons.

1
user203319

Beachten Sie, dass das Einfügen der UTF-8-Stückliste nicht unbedingt eine gute Idee ist - Mac-Versionen von Excel ignorieren diese und zeigen die Stückliste tatsächlich als ASCII an… drei unangenehme Zeichen am Anfang des ersten Felds in Ihrer Tabelle…

1
Ned Martin

Eine andere Lösung, die ich gefunden habe, bestand darin, das Ergebnis einfach als Windows Code Page 1252 (Windows-1252 oder CP1252) zu kodieren. Dies würde zum Beispiel durch Setzen von Content-Type passend zu so etwas wie text/csv; charset=Windows-1252 und stellen Sie die Zeichenkodierung des Antwortstroms ähnlich ein.

1
creechy

Ich kann CSV nur dazu bringen, in Excel 2007 als tabulatorgetrenntes Little-Endian-UTF-16, beginnend mit der richtigen Bytereihenfolgemarkierung, richtig zu analysieren.

1

Das Schreiben einer Stückliste in die Ausgabe-CSV-Datei hat in Django tatsächlich funktioniert:

def handlePersoonListExport(request):
    # Retrieve a query_set
    ...

    template = loader.get_template("export.csv")
    context = Context({
        'data': query_set,
    })

    response = HttpResponse()
    response['Content-Disposition'] = 'attachment; filename=export.csv'
    response['Content-Type'] = 'text/csv; charset=utf-8'
    response.write("\xEF\xBB\xBF")
    response.write(template.render(context))

    return response

Für weitere Informationen http://crashcoursing.blogspot.com/2011/05/exporting-csv-with-special-characters.html Danke Jungs!

1
Lukas Batteau

Dies ist nur eine Frage der Zeichenkodierung. Es sieht so aus, als würden Sie Ihre Daten als UTF-8 exportieren: é in UTF-8 ist die Zwei-Byte-Sequenz 0xC3 0xA9, die in Windows-1252 als é interpretiert wird. Stellen Sie beim Importieren Ihrer Daten in Excel sicher, dass die verwendete Zeichenkodierung UTF-8 ist.

1
Adam Rosenfield

Ich habe einen Weg gefunden, das Problem zu lösen. Dies ist ein übler Hack, aber er funktioniert: Öffnen Sie das Dokument mit Open Office und speichern Sie es in einem beliebigen Excel-Format. das resultierende .xls oder .xlsx zeigt die akzentuierten Zeichen an.

0
Fred Reillier

Wenn Sie in vb.net einen älteren Code haben, wie ich ihn habe, hat der folgende Code für mich funktioniert:

    Response.Clear()
    Response.ClearHeaders()
    Response.ContentType = "text/csv"
    Response.Expires = 0
    Response.AddHeader("Content-Disposition", "attachment; filename=export.csv;")
    Using sw As StreamWriter = New StreamWriter(Context.Response.OutputStream, System.Text.Encoding.Unicode)
        sw.Write(csv)
        sw.Close()
    End Using
    Response.End()
0
Johann

Überprüfen Sie die Codierung, in der Sie die Datei generieren. Damit Excel die Datei korrekt anzeigt, müssen Sie die Standard-Codepage des Systems verwenden.

Welche Sprache verwenden Sie? Wenn es sich um .NET handelt, müssen Sie beim Generieren der Datei nur Encoding.Default verwenden.

0
albertein

Mit Ruby 1.8.7 verschlüssele ich jedes Feld nach UTF-16 und verwerfe die Stückliste (vielleicht).

Der folgende Code wird aus active_scaffold_export extrahiert:

<%                                                                                                                                                                                                                                                                                                                           
      require 'fastercsv'                                                                                                                                                                                                                                                                                                        
      fcsv_options = {                                                                                                                                                                                                                                                                                                           
        :row_sep => "\n",                                                                                                                                                                                                                                                                                                        
        :col_sep => params[:delimiter],                                                                                                                                                                                                                                                                                          
        :force_quotes => @export_config.force_quotes,                                                                                                                                                                                                                                                                            
        :headers => @export_columns.collect { |column| format_export_column_header_name(column) }                                                                                                                                                                                                                                
      }                                                                                                                                                                                                                                                                                                                          

      data = FasterCSV.generate(fcsv_options) do |csv|                                                                                                                                                                                                                                                                           
        csv << fcsv_options[:headers] unless params[:skip_header] == 'true'                                                                                                                                                                                                                                                      
        @records.each do |record|                                                                                                                                                                                                                                                                                                
          csv << @export_columns.collect { |column|                                                                                                                                                                                                                                                                              
            # Convert to UTF-16 discarding the BOM, required for Excel (> 2003 ?)                                                                                                                                                                                                                                     
            Iconv.conv('UTF-16', 'UTF-8', get_export_column_value(record, column))[2..-1]                                                                                                                                                                                                                                        
          }                                                                                                                                                                                                                                                                                                                      
        end                                                                                                                                                                                                                                                                                                                      
      end                                                                                                                                                                                                                                                                                                                        
    -%><%= data -%>

Die wichtige Zeile lautet:

Iconv.conv('UTF-16', 'UTF-8', get_export_column_value(record, column))[2..-1]
0