Microsoft Excel wprowadza znaki diakrytyczne w.pliki csv?

Programowo eksportuję dane (za pomocą PHP 5.2) doplik testowy csv.
Przykładowe dane: Numéro 1 (zwróć uwagę na akcentowane e). Dane to utf-8 (no prepended BOM).

Kiedy otwieram ten plik w MS Excel jest wyświetlany jako Numéro 1.

Jestem w stanie otworzyć to w edytorze tekstu (UltraEdit), który wyświetla go poprawnie. UE podaje, że znakiem jest decimal 233.

Jak mogę eksportować tekst dane wplik csv tak aby MS Excel poprawnie renderować go, najlepiej bez wymuszania użycia kreatora importu lub niestandardowych ustawień kreatora?

Author: bandrade, 2008-09-30

22 answers

Poprawnie sformatowany plik UTF8 może mieć znak w kolejności bajtów jako pierwsze trzy oktety. Są to wartości szesnastkowe 0xEF, 0xbb, 0xbf. Oktety te służą do oznaczania pliku jako UTF8 (ponieważ nie są istotne jako informacja o "kolejności bajtów").1 Jeśli ten BOM nie istnieje, konsument / czytelnik może wywnioskować typ kodowania tekstu. Czytniki, które nie są zdolne do UTF8, będą odczytywać bajty jako inne kodowanie, takie jak Windows-1252 i wyświetlać znaki  w początek pliku.

Znany jest błąd, w którym Excel, otwierając pliki UTF8 CSV poprzez skojarzenie plików, zakłada, że są one w kodowaniu jednobajtowym, pomijając obecność BOM UTF8. To może nie być naprawione przez domyślne ustawienia domyślnej strony kodowej lub języka. BOM nie będzie wskazywać w Excelu - po prostu nie zadziała. (Raport mniejszości twierdzi, że BOM czasami uruchamia Kreator "Importuj tekst".) Ten błąd wydaje się istnieć w Excelu 2003 i wcześniejszych. Większość raportów (wśród odpowiedzi tutaj) mówi, że jest to naprawione w Excelu 2007 i nowszych.

Zauważ, że możesz zawsze* poprawnie otwierać pliki UTF8 CSV w programie Excel za pomocą Kreatora "Importuj tekst", który pozwala określić kodowanie otwieranego pliku. Oczywiście jest to znacznie mniej wygodne.

Czytelnicy tej odpowiedzi są najprawdopodobniej w sytuacji, w której nie obsługują Excela à i innymi podobnymi oknami - 1252 znaki. dodanie BOM UTF8 jest prawdopodobnie najlepszą i najszybszą poprawką.

Jeśli utkniesz z użytkownikami na starszych Excelach, a Excel jest jedynym konsumentem Twoich plików CSV, możesz obejść to, eksportując UTF16 zamiast UTF8. Excel 2000 i 2003 będą dwukrotnie klikać-otwierać je poprawnie. (Niektóre inne edytory tekstu mogą mieć problemy z UTF16, więc być może będziesz musiał rozważyć swoje opcje ostrożnie.)


* Z wyjątkiem sytuacji, gdy nie możesz, (przynajmniej) Kreator importu programu Excel 2011 Dla Komputerów Mac nie zawsze działa ze wszystkimi kodowaniami, niezależnie od tego, co mu powiesz. > :)

 249
Author: James Baker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-16 20:52:59

Prepending BOM (\uFEFF) zadziałało dla mnie (Excel 2007) , w tym Excel rozpoznał plik jako UTF-8. W przeciwnym razie zapisywanie go i korzystanie z Kreatora importu działa, ale jest mniej idealne.

 42
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-24 17:11:18

Poniżej znajduje się kod PHP, którego używam w projekcie przy wysyłaniu programu Microsoft Excel do użytkownika:

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

Aktualizacja: ulepszenie nazwy pliku i naprawienie błędu poprawne obliczanie długości. Dzięki TRiG i @ivanhoe011

 32
Author: Marc Carlucci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:14

ODPOWIEDŹ dla wszystkich kombinacji wersji Excela (2003 + 2007) i typów plików

Większość innych odpowiedzi dotyczy tylko ich wersji programu Excel i niekoniecznie ci pomoże, ponieważ ich odpowiedź może nie być prawdziwa dla twojej wersji programu Excel.

Na przykład dodanie znaku BOM powoduje problemy z automatycznym rozpoznawaniem separatora kolumn, ale nie w każdej wersji programu Excel.

Istnieją 3 zmienne, które określają, czy działa w większości Excel wersje:

  • kodowanie
  • obecność znaków BOM
  • Separator komórek

Ktoś stoicki w SAP wypróbował każdą kombinację i zgłosił wynik. Efekt końcowy? Użyj UTF16le ze znakami BOM i tab jako separatora, aby działał w większości wersji programu Excel.

Nie wierzysz mi? Ja też nie, ale czytaj tutaj i płacz: http://wiki.sdn.sap.com/wiki/display/ABAP/CSV + testy + kodowania + i + kolumny + separatora

 13
Author: Christiaan Westerbeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-11 09:59:57

Wybierz kodowanie UTF - 8 podczas importowania. jeśli używasz pakietu Office 2007, To właśnie tam go wybrałeś : zaraz po otwarciu pliku.

 10
Author: daniels,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-19 02:01:01

Echo UTF-8 BOM przed wysłaniem danych CSV. Rozwiązuje to wszystkie problemy z postaciami w systemie Windows, ale nie działa na komputerach Mac.

echo "\xEF\xBB\xBF";

To działa dla mnie, ponieważ muszę wygenerować plik, który będzie używany tylko na komputerach z systemem Windows.

 9
Author: Johal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-12 14:33:14

UTF-8 nie działa mi w office 2007 bez dodatku service pack, z BOM lub bez (U+ffef lub 0xEF, 0xbb, 0xbf, ani nie działa) instalacja sp3 sprawia, że UTF-8 działa, gdy 0xef,0xbb, 0xbf BOM jest poprzedzone.

UTF-16 działa podczas kodowania w Pythonie przy użyciu "utf-16-le" z 0xFF 0xef BOM prepended i za pomocą tab jako separator. Musiałem ręcznie wypisać BOM, a następnie użyć "utf-16-le "zamiast" utf-16", w przeciwnym razie każda encode() poprzedzała BOM do każdego wiersza wypisanego, który pojawił się jako śmieci na pierwszej kolumnie drugiej linii i po.

Nie wiadomo czy UTF-16 będzie działał bez zainstalowanego sp, ponieważ Nie mogę teraz wrócić. sigh

To jest na windows, nie wiem o office for MAC.

Dla obu przypadków roboczych, import działa przy uruchamianiu pobierania bezpośrednio z przeglądarka i Kreator importu tekstu nie interweniują, działa tak, jak można się spodziewać.

 7
Author: gerald dol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-18 00:03:28

Jak powiedział Fregal \ uFEFF jest drogą do zrobienia.

<%@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
Author: Kristof Neirynck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-27 17:29:40

Zauważyłem również, że pytanie zostało "odpowiedział" jakiś czas temu, ale nie rozumiem opowieści, które mówią, że nie można otworzyć plik csv kodowany utf8 pomyślnie w Excelu bez użycia kreatora tekstu.

Moje powtarzalne doświadczenie: Wpisz Old MacDonald had a farm,ÈÌÉÍØ do Notatnika, naciśnij Enter, a następnie Zapisz jako (używając opcji UTF-8).

Używanie Pythona do pokazania, co tam jest:

>>> 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
Dobrze. Notatnik umieścił BOM z przodu.

Teraz przejdź do Eksploratora Windows, kliknij dwukrotnie na nazwę pliku lub kliknij prawym przyciskiem myszy i użyj "Otwórz za pomocą ...", a w górę wyskakuje Excel (2003) z wyświetlaczem zgodnie z oczekiwaniami.

 3
Author: John Machin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-12 03:01:12

Możesz zapisać plik html z rozszerzeniem ' xls ' i akcenty będą działać (przynajmniej przed 2007).

Przykład: zapisz to (używając Zapisz jako utf8 w Notatniku) jako 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
Author: Benjol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 18:46:29

To tylko kwestia kodowania znaków. Wygląda na to, że eksportujesz swoje dane jako UTF - 8: é w UTF-8 jest dwubajtową sekwencją 0xC3 0xA9, która po interpretacji w Windows-1252 jest é. Podczas importowania danych do programu Excel upewnij się, że kodowanie znaków, którego używasz, to UTF-8.

 1
Author: Adam Rosenfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 21:11:09

Format CSV jest zaimplementowany jako ASCII, a nie unicode, w Excelu, co zniekształca znaki diakrytyczne. Doświadczyliśmy tego samego problemu, w ten sposób odkryłem, że oficjalny standard CSV został zdefiniowany jako oparty na ASCII w Excelu.

 1
Author: Jeff Yates,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 21:30:01

Excel 2007 poprawnie odczytuje UTF - 8 z BOM (EF BB BF) zakodowanym csv.

Excel 2003 (i być może wcześniej) odczytuje UTF-16LE z BOM (FF FE), ale z tabulatorami zamiast przecinków lub średników.

 1
Author: user203319,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-05 09:56:03

Mogę tylko zmusić CSV do poprawnego parsowania w Excelu 2007 jako oddzielony tabulatorem little-endian UTF-16, zaczynając od właściwego znaku kolejności bajtów.

 1
Author: Manfred Stienstra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-09 13:22:14

Zapisanie BOM do wyjściowego pliku CSV faktycznie zadziałało dla mnie w 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

Po Więcej informacji http://crashcoursing.blogspot.com/2011/05/exporting-csv-with-special-characters.html Dzięki chłopaki!

 1
Author: Lukas Batteau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-26 13:16:14

Innym rozwiązaniem, które znalazłem, było zakodowanie wyniku jako strony kodowej systemu windows 1252(Windows-1252 lub CP1252). Można to zrobić, na przykład ustawiając Content-Type odpowiednio na coś w rodzaju text/csv; charset=Windows-1252 i podobnie ustawiając kodowanie znaków strumienia odpowiedzi.

 1
Author: creechy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-19 15:44:32

Zauważ, że włączenie BOM UTF-8 niekoniecznie jest dobrym pomysłem-Mac wersje Excela ignorują go i faktycznie wyświetli BOM jako ASCII... trzy paskudne znaki na początku pierwszego pola w arkuszu kalkulacyjnym...

 1
Author: Ned Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-20 04:26:02

Sprawdź kodowanie, w którym generujesz plik, aby excel wyświetlał plik poprawnie musisz użyć domyślnej strony kodowej systemu.

Jakiego języka używasz? jeśli jest to. Net, wystarczy użyć kodowania.Domyślne podczas generowania pliku.

 0
Author: albertein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 21:12:25

Jeśli masz kod legacy w vb.net podobnie jak ja, działał dla mnie następujący kod:

    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
Author: Johann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 11:06:04

Znalazłem sposób na rozwiązanie problemu. Jest to paskudny hack, ale działa: otwórz dokument za pomocą Open Office, a następnie zapisz go do dowolnego formatu Excela; wynikowe .xls LUB .xlsx wyświetli akcentowane znaki.

 0
Author: Fred Reillier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-05 18:44:26

Z Ruby 1.8.7 koduję każde pole do UTF-16 i odrzucam BOM (być może).

Z active_scaffold_export wyodrębniono następujący kod:

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

Ważny wiersz to:

Iconv.conv('UTF-16', 'UTF-8', get_export_column_value(record, column))[2..-1]
 0
Author: Antonio Bardazzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 07:52:31

Otwórz plik csv za pomocą notepad++ kliknij na kodowanie, wybierz Konwertuj na UTF-8 (nie Konwertuj na UTF-8 (bez BOM)) Zapisz Otwórz za pomocą double clic z Excelem Hope that help Christophe GRISON

 -2
Author: Christophe GRISON,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-25 16:54:44