Domanda

Sto esportando a livello di codice i dati (usando PHP 5.2) in un file di test .csv.
Dati di esempio: Numéro 1 (notare la e accentata). I dati sono utf-8 (nessuna distinta base anticipata).

Quando apro questo file in MS Excel viene visualizzato come Numéro 1.

Sono in grado di aprirlo in un editor di testo (UltraEdit) che lo visualizza correttamente. UE riporta che il personaggio è decimal 233.

Come posso esportare testo dati in un file .csv in modo che MS Excel lo visualizzerà correttamente , preferibilmente senza forzare l'uso della procedura guidata di importazione, oppure impostazioni della procedura guidata predefinita?

È stato utile?

Soluzione

Un file UTF8 correttamente formattato può avere un Contrassegno byte come primi tre ottetti. Questi sono i valori esadecimali 0xEF, 0xBB, 0xBF. Questi ottetti servono a contrassegnare il file come UTF8 (poiché non sono rilevanti come & Quot; ordine byte & Quot; informazioni). 1 Se questa DBA non esiste, il consumatore / lettore viene lasciato a dedurre il tipo di codifica del testo. I lettori che non sono in grado di utilizzare UTF8 leggeranno i byte come altre codifiche come Windows-1252 e visualizzeranno i caratteri  all'inizio del file.

Esiste un bug noto in cui Excel, all'apertura dei file CSV UTF8 tramite l'associazione dei file, presuppone che si trovino in una codifica a byte singolo, ignorando la presenza della DBA UTF8. Questo non può essere corretto da qualsiasi codepage o impostazione della lingua predefinita del sistema. La distinta componenti non verrà individuata in Excel, ma semplicemente non funzionerà. (Un rapporto di minoranza afferma che la DBA a volte attiva la procedura guidata & Quot; Importa testo & Quot;). Questo errore sembra esistere in Excel 2003 e precedenti. La maggior parte dei rapporti (tra le risposte qui) afferma che ciò è stato risolto in Excel 2007 e versioni successive.

Nota che puoi sempre * aprire correttamente i file CSV UTF8 in Excel usando il " Importa testo " procedura guidata, che consente di specificare la codifica del file che si sta aprendo. Naturalmente questo è molto meno conveniente.

I lettori di questa risposta sono molto probabilmente in una situazione in cui non supportano particolarmente Excel < 2007, ma stanno inviando testo non elaborato UTF8 a Excel, che lo interpreta in modo errato e cosparge il testo con à e altri caratteri simili di Windows-1252. L'aggiunta della DBA UTF8 è probabilmente la soluzione migliore e più rapida.

Se sei bloccato con utenti su Excels meno recenti ed Excel è l'unico consumatore dei tuoi CSV, puoi aggirare questo problema esportando UTF16 invece di UTF8. Excel 2000 e 2003 fanno doppio clic per aprirli correttamente. (Alcuni altri editor di testo possono avere problemi con UTF16, quindi potrebbe essere necessario valutare attentamente le opzioni.)


* Tranne quando non puoi, (almeno) l'importazione guidata di Excel 2011 per Mac in realtà non funziona sempre con tutte le codifiche, indipendentemente da ciò che dici. lt &; & / aneddotica evidenza gt; :)

Altri suggerimenti

Preparare una DBA (\ uFEFF) ha funzionato per me (Excel 2007), in quanto Excel ha riconosciuto il file come UTF-8. Altrimenti, salvarlo e utilizzare la procedura guidata di importazione funziona, ma è meno ideale.

Di seguito è riportato il codice PHP che utilizzo nel mio progetto quando invio Microsoft Excel all'utente:

  /**
   * 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;
  }

AGGIORNATO: il miglioramento del nome file e BUG correggono il calcolo della lunghezza corretta. Grazie a TRiG e @ ivanhoe011

La risposta per tutte le combinazioni di versioni di Excel (2003 + 2007) e tipi di file

La maggior parte delle altre risposte qui riguarda solo la loro versione di Excel e non ti aiuterà necessariamente, perché la loro risposta potrebbe non essere vera per la tua versione di Excel.

Ad esempio, l'aggiunta del carattere DBA introduce problemi con il riconoscimento automatico del separatore di colonne, ma non con tutte le versioni di Excel.

Esistono 3 variabili che determinano se funziona nella maggior parte delle versioni di Excel:

  • Codifica
  • Presenza carattere DBA
  • Separatore di celle

Qualcuno stoico in SAP ha provato ogni combinazione e riportato il risultato. Risultato finale? Usa UTF16le con la distinta componenti e il carattere di tabulazione come separatore per farlo funzionare nella maggior parte delle versioni di Excel.

Non mi credi? Nemmeno io, ma leggi qui e piangi: http://wiki.sdn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator

seleziona la codifica UTF-8 durante l'importazione. se usi Office 2007 è qui che l'hai scelto: subito dopo aver aperto il file.

Echo UTF-8 BOM prima di emettere dati CSV. Questo risolve tutti i problemi relativi ai personaggi in Windows ma non funziona per Mac.

echo "\xEF\xBB\xBF";

Funziona per me perché ho bisogno di generare un file che verrà utilizzato solo su PC Windows.

UTF-8 non funziona per me in Office 2007 senza alcun service pack, con o senza DBA (U + ffef o 0xEF, 0xBB, 0xBF, né funziona) l'installazione di sp3 fa funzionare UTF-8 quando viene anteposta 0xEF, 0xBB, 0xBF BOM.

UTF-16 funziona durante la codifica in Python usando " utf-16-le " con uno 0xff 0xef BOM anteposta e utilizzo della scheda come separatore. Ho dovuto scrivere manualmente la DBA, quindi usare & Quot; utf-16-le & Quot; piuttosto che " utf-16 " ;, altrimenti ogni encode () ha anteposto la distinta base a ogni riga scritta quale è apparso come immondizia sulla prima colonna della seconda riga e dopo.

non può dire se UTF-16 funzionerebbe senza alcun sp installato, da allora Non posso tornare indietro ora. sospirare

Questo è su Windows, non so di Office per MAC.

per entrambi i casi di lavoro, l'importazione funziona all'avvio di un download direttamente da il browser e la procedura guidata di importazione del testo non intervengono, funzionano come ci si aspetterebbe.

Come ha detto Fregal \ uFEFF è la strada da percorrere.

<%@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
%>

Ho anche notato che la domanda era " ha risposto " qualche tempo fa, ma non capisco le storie che dicono che non puoi aprire correttamente un file csv con codifica utf8 in Excel senza usare la procedura guidata di testo.

La mia esperienza riproducibile: Digita Old MacDonald had a farm,ÈÌÉÍØ in Blocco note, premi Invio, quindi Salva con nome (usando l'opzione UTF-8).

Usare Python per mostrare cosa c'è realmente dentro:

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

Buona. Blocco note ha messo una DBA in primo piano.

Ora vai in Esplora risorse, fai doppio clic sul nome del file o fai clic con il pulsante destro del mouse e usa " Apri con ... " ;, e fai apparire Excel (2003) con la visualizzazione come previsto.

Puoi salvare un file html con l'estensione 'xls' e gli accenti funzioneranno (almeno prima del 2007).

Esempio: salvalo (usando Salva come utf8 nel Blocco note) come 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>

Questa è solo una questione di codifiche di caratteri. Sembra che tu stia esportando i tuoi dati come UTF-8: & # 233; in UTF-8 è la sequenza a due byte 0xC3 0xA9, che quando interpretata in Windows-1252 è & # 195; & # 169 ;. Quando importi i tuoi dati in Excel, assicurati di dire che la codifica dei caratteri che stai utilizzando è UTF-8.

Il formato CSV è implementato come ASCII, non unicode, in Excel, alterando così i segni diacritici. Abbiamo riscontrato lo stesso problema, ovvero il modo in cui ho rintracciato che lo standard CSV ufficiale è stato definito come basato su ASCII in Excel.

Scrivere una DBA nel file CSV di output ha funzionato per me in Django:

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

Per maggiori informazioni http: //crashcoursing.blogspot .com / 2011/05 / export-csv-with-special-characters.html Grazie ragazzi!

Un'altra soluzione che ho trovato è stata quella di codificare il risultato come pagina di codice di Windows 1252 (Windows-1252 o CP1252). Ciò verrebbe fatto, ad esempio impostando Content-Type in modo appropriato su qualcosa come text/csv; charset=Windows-1252 e impostando la codifica dei caratteri del flusso di risposta in modo simile.

Nota che includere la distinta base UTF-8 non è necessariamente una buona idea: le versioni Mac di Excel la ignorano e visualizzeranno effettivamente la distinta come ASCII & # 8230; tre personaggi cattivi all'inizio del primo campo nel foglio di calcolo & # 8230;

Controlla la codifica in cui stai generando il file, per fare in modo che Excel visualizzi correttamente il file devi usare la tabella codici predefinita del sistema.

Quale lingua stai usando? se è .Net devi solo usare Encoding.Default durante la generazione del file.

Excel 2007 legge correttamente UTF-8 con CSV con codifica BOM (EF BB BF)

Excel 2003 (e forse prima) legge UTF-16LE con BOM (FF FE), ma con TAB anziché virgole o punti e virgola.

Posso solo fare in modo che CSV analizzi correttamente in Excel 2007 come UTF-16 little-endian separato da tabulazioni a partire dal segno di ordine byte corretto.

Se hai un codice legacy in vb.net come me, il seguente codice ha funzionato per me:

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

Ho trovato un modo per risolvere il problema. Questo è un brutto trucco ma funziona: apri il documento con Apri Office , quindi salvalo in qualsiasi formato Excel; il .xls o .xlsx risultante visualizzerà i caratteri accentati.

Con Ruby 1.8.7 codifico tutti i campi in UTF-16 e scarto la distinta base (forse).

Il seguente codice viene estratto da active_scaffold_export:

<%                                                                                                                                                                                                                                                                                                                           
      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 -%>

La linea importante è:

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

apri il file csv con notepad ++ fare clic su Encode, selezionare Converti in UTF-8 (non convertire in UTF-8 (senza BOM)) Salvare aperto con doppio clic con Excel Spero che ti aiuti Christophe GRISON

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top