Microsoft Excelは.csvファイルの発音区別符号を壊しますか?


190

プログラムでデータを(PHP 5.2を使用して).csvテストファイルにエクスポートしています。
データの例:( Numéro 1アクセント付きのeに注意してください)。データはutf-8(追加されたBOMなし)です。

このファイルをMS Excelで開くと、と表示されNuméro 1ます。

これを正しく表示するテキストエディター(UltraEdit)で開くことができます。UEは文字がであることを報告しますdecimal 233

テキストデータを.csvファイルにエクスポートし、MS Excelで、できればインポートウィザードやデフォルト以外のウィザード設定を強制せずに正しくレンダリングできるようにするにはどうすればよいですか?


私はうまくいかなかった "EF BB BF"を試したので、あなたのBOMソリューションについてもっと知りたいと思います。
James Baker、

3
選択された実用的なソリューションは次のとおりです。* BOMを含める。utf-8 *次のヘッダーを使用: 'Content-type:text / plain; charset = utf-8 'これはExcel 2003およびExcel 2007で「機能しました」-機能した=インポートウィザードなしで開かれ、発音区別符号が正しくレンダリングされました。BOMが必要であることを確認しませんでした。
Freddo411 2008年

2
BOMが必要です。今テストしました。これがないと、特殊文字は正常にレンダリングされません。
Alex Ciminian、2010年

2
誰かがBOM(バイトオーダーマーカー)を追加する方法についてもっと誰かが言うことができればそれを愛するでしょう。Response.Write(EF BB BF ")のようなものを実行すると、これらの文字はファイルの先頭に表示されます
sydneyos

シドニー:ファーガルが以下に言うように; 文字列の前に\ uFEFFを追加します。
noocyte:2011年

回答:


242

正しくフォーマットされたUTF8ファイルには、最初の3つのオクテットとしてバイトオーダーマークを含めることができます。これらは16進値0xEF、0xBB、0xBFです。これらのオクテットは、ファイルをUTF8としてマークするのに役立ちます(「バイトオーダー」情報としては関係がないため)。1 このBOMが存在しない場合、コンシューマー/リーダーは、テキストのエンコードタイプを推測する必要があります。UTF8非対応のリーダーは、バイトをWindows-1252などの他のエンコーディングとして読み取り、ファイルの先頭に文字を表示します。

Excelがファイルの関連付けを介してUTF8 CSVファイルを開くと、UTF8 BOMの存在を無視して、それらが1バイトエンコーディングであると想定する既知のバグがあります。これは、システムのデフォルトのコードページまたは言語設定では修正できません。BOMはExcelでは手掛かりを取得しません-機能しません。(少数の報告では、BOMが「テキストのインポート」ウィザードをトリガーすることがあると主張しています。)このバグはExcel 2003以前に存在するようです。ほとんどのレポート(ここで回答を確認)では、これはExcel 2007以降で修正されているとされています。

開いているファイルのエンコーディングを指定できる「テキストのインポート」ウィザードを使用して、ExcelでUTF8 CSVファイルをいつでも正しく*開くことができることに注意してください。もちろん、これはあまり便利ではありません。

この回答の読者は、Excel 2007を特にサポートしていない状況で最も可能性が高いですが、未加工のUTF8テキストをExcelに送信していますÃUTF8 BOMを追加することは、おそらく最善かつ最も迅速な修正です。

古いExcelのユーザーに悩まされていて、ExcelがCSVの唯一の利用者である場合、UTF8ではなくUTF16をエクスポートすることでこれを回避できます。Excel 2000および2003は、これらを正しくダブルクリックして開きます。(他の一部のテキストエディターではUTF16で問題が発生する可能性があるため、オプションを慎重に検討する必要があります。)


*できない場合を除いて、(少なくとも)Excel 2011 for Macのインポートウィザードは、ユーザーの指示に関係なく、実際には常にすべてのエンコーディングで機能するわけではありません。</ anecdotal-evidence> :)


14
エンコーディングを指定する場所を見つけるために私を永遠に連れて行きました。[保存]ダイアログ> [ツール]ボタン> [Webオプション]> [エンコード]タブ。彼らは確かにそのような重要なものを隠すのが得意です。
Triynko、

6
間違っ:UTF-8のファイルのロードにBOMを追加し、そのファイルを正しくエクセル2007でインポートウィザード必要とせず
ビクターニコレット

3
私たちはビクターが今日言っているのと同じことを見つけました(Excel 2010を使用して、それは私たちが利用できたすべてです)。UTF-8 BOM / Signature(EF BB BF)を追加すると、システムのデフォルトエンコーディングを使用したダブルクリックが修正され、UTF8が正しく使用されるようになりました:)
Danny Tuppeny

20
一般に、UTF-8でエンコードされたファイルには、バイトオーダーマークを付加しないでください。UTF-8には可変バイトオーダーがなく、そこに置くとUTF-8のASCII互換性が妨害されます。UTF-8 faux-BOMを許可または推奨する特定のファイル形式がいくつかありますが、それ以外の場合は避けてください。CSVは完全にエンコードを無視するため、特定のツールがバイトシーケンス0xEF 0xBB 0xBFをUTF-8のインジケーターとして解釈するかどうかは誰もが推測します。最初のセルの非表示の制御文字。最初のセルの文字。または完全に何か他のもの。
ボビンス2012

3
@Ian:BOM 付きのUTF-8 あることは誰にもわかりません-0xEF 0xBB 0xBFは、ほとんどのレガシーエンコーディングでも有効なシーケンスです(そのため、ISO-8859-1またはcp1252として誤って解釈され、と表示されることがよくあります)。これは、推測アルゴリズム、およびそれを特に許容するファイル形式(XMLなど)にのみ役立ちます。UTF-8ファイルにfaux-BOMを含めることの欠点は、ASCII互換性(UTF-8の主なセールスポイント)を損なうことです。多くのエンコードを無視するテキストツールは、予期しない主要なfaux-BOMに直面すると壊れます。
ボビンス2012

39

ExcelがファイルをUTF-8として認識するという点で、BOM(\ uFEFF)を前に追加することで機能しました(Excel 2007)。それ以外の場合は、保存してインポートウィザードを使用しても機能しますが、あまり理想的ではありません。


1
それでもテキストインポートウィザードが開くので、違いはダブルクリックするだけなので、理想的ではありませんが、とにかく唯一の既知のソリューションです。
haridsv 2010

私にとっては、何のインポートウィザードは、Excel 2007で表示されない
ビクターニコレット

私にとってもインポートウィザードはありません-UTF8 BOM / Signature(EF BB BF)が存在する場合、期待どおりに動作します。
ダニーTuppeny

また、\ufeffあるUTF-16(BE)BOMないUTF-8 BOM
アラステア・マコーマック

2
いいえ、@ AlastairMcCormack、どちらかです。エンコード方法によって異なります。UTF-8としてエンコードされた「\ ufeff」は、まさにEF BB BFです。(UTF-16としてエンコードされ、2バイトになります。)
Dave Burt

30

以下は、Microsoft Excelをユーザーに送信するときにプロジェクトで使用するPHPコードです。

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

更新:ファイル名の改善とバグ修正により、正しい長さの計算。おかげTRIG@ ivanhoe011


1
このページで他のいくつかの提案を試しましたが、Excel 2007ではこれでうまくいきました。最も重要な変更は、コンマの代わりにタブを使用することです(.csvファイルであっても)。 mb_convert_encoding()を呼び出します。また、mb_convert_encoding()のサポートを得るために、-enable-mbstringを使用してPHPを再コンパイルする必要がありました。ありがとう!
ラッセルG

1
これは私にとってもうまくいきました、ありがとう。しかし、Safariの私には私のコンソール「リソースを文書として解釈けどとして...転送」が判断し、WebKitの癖だ私は推測でエラーが出るstackoverflow.com/questions/3899426/...を、おそらくそれはだていないおよび/または誰かが持っています解決策を見つけました。さらに、あなたの例では、変更を提案します'Content-Disposition: attachment; filename="'.$filename.'.csv"'。Firefoxは二重引用符を必要とするため、スペースがないとファイル名が切り捨てられます。
カシミール2012年

CSV(text/csv)を出力しているのに、Excel(application/vnd.ms-excel)と呼んでいるのはなぜですか?
TRiG 2013年

2
これはうまくいきます!Macでも動作していることを確認できます(Office 2011)。
ジョナサン

これはいけませんheader('Content-Length: '. mb_strlen($encoded_csv, 'UTF-16LE'));か?
リッチブラッドショー

13

Excelバージョン(2003 + 2007)とファイルタイプのすべての組み合わせに対する答え

ここでの他のほとんどの回答は、Excelのバージョンにのみ関係し、必ずしも役立つとは限りません。回答がお使いのバージョンのExcelに当てはまらない場合があるためです。

たとえば、BOM文字を追加すると、列区切りの自動認識に問題が生じますが、Excelのすべてのバージョンに問題があるわけではありません。

ほとんどのExcelバージョンで機能するかどうかを決定する3つの変数があります。

  • エンコーディング
  • BOMキャラクターの存在
  • セルセパレーター

SAPのストイックな人がすべての組み合わせを試し、結果を報告しました。最終結果?ほとんどのExcelバージョンで機能するように、BOMとタブ文字をセパレーターとしてUTF16leを使用します。

あなたは私を信じていませんか?私もそうしませんが、ここを読んで泣きます:http : //wiki.sdn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator


単に追加するsep=,か、使用したいものは何ですか?すでにBOMを追加している場合は、ファイルにコンテンツを追加することを嫌っていないと思います。
ケーシー

ええ、実際、私自身の質問に答えるには、フィールドセパレーター宣言を追加しないでください。これにより、このトリックが機能しなくなるためです。つまり、ユーザーが間違った地域設定をしていると、基本的に文字化けしたり、ファイルがCSVとして正しく解釈されなかったりします。
ケーシー

1
utf-16le + BOM(0xFF 0xFE)+タブが最適
zhaozhi

10

インポート時にUTF-8エンコードを選択します。Office 2007を使用している場合は、ここで選択します。ファイルを開いた直後です。


1
これは便利です。ウィザードに頼らずにこれを行う方法を尋ねる質問を変更しました
Freddo411

9

CSVデータを出力する前にUTF-8 BOMをエコーし​​ます。これにより、Windowsのすべてのキャラクターの問題が修正されますが、Macでは機能しません。

echo "\xEF\xBB\xBF";

Windows PCでのみ使用されるファイルを生成する必要があるため、これは私にとっては機能します。


すべてのタイプの列セパレーターやすべてのExcelバージョンに当てはまるわけではありません。以下の私の答えを読んでください(今のところ)。
Christiaan Westerbeek、2014年

7

BOM(U + ffefまたは0xEF、0xBB、0xBF、どちらも機能しない)の有無にかかわらず、サービスパックなしでは、UTF-8がOffice 2007で機能しません。先頭に追加。

UTF-16は、「utf-16-le」を0xff 0xef BOMを前に付加し、タブをセパレーターとして使用してPythonでエンコードするときに機能します。手動でBOMを書き出してから、「utf-16」ではなく「utf-16-le」を使用する必要がありました。それ以外の場合、各encode()は、書き出されたすべての行にBOMを追加しました。 2行目以降。

spがインストールされていなくてもUTF-16が機能するかどうかはわかりません。はぁ

これはウィンドウズ上にあり、MACのオフィスについては知らない。

どちらの場合も、ブラウザーから直接ダウンロードを起動するとインポートが機能し、テキストインポートウィザードは機能しません。期待どおりに機能します。


Excel 2011 for Macでも動作します。
アダム

投稿ありがとうございます。office2007 sp3をインストールしていなくてもutf-16leを使用できますが、BOMは0xFF 0xFE
zhaozhi

4

Fregalが言ったように、\ uFEFFは進むべき道です。

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

1
BOMを使用する場合、Excel 2007でタブセパレーターが無視される方法を確認してください。あなたはもっと何かを考え出す必要があります。
Christiaan Westerbeek、2013

3

少し前に質問に「回答」されたことにも気づきましたが、テキストウィザードを使用しないと、utf8でエンコードされたcsvファイルをExcelで正常に開けないという話を理解できません。

私の再現可能なエクスペリエンス:Old MacDonald had a farm,ÈÌÉÍØメモ帳に入力し、Enterキーを押してから、(UTF-8オプションを使用して)名前を付けて保存します。

Pythonを使用して実際にそこにあるものを示す:

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

良い。メモ帳は前面にBOMを配置しています。

Windowsエクスプローラーに移動し、ファイル名をダブルクリックするか、右クリックして[...で開く]を使用すると、期待どおりに表示されるExcel(2003)がポップアップ表示されます。


@Cocowalla:まあ、私はこれを試してみただけで(もう一度、投稿する前にテストしました)、Excel 2007(現在使用しているもの)で動作しました。open('oldmac.csv', 'rb').read()入力を確認するために行いましたか?
John Machin、

私はExcel 2007を試していません(Excel 2007がBOMでUTF-8ファイルを正常に読み取ることを知っています)、Excel 2003を試しました
Cocowalla

@Cocowalla:ええと、Excel 2003を使用していたときはうまくいきました。Excel 2003の最新のService Packを使用していますか?私が提案したとおりに入力を確認しましたか?
John Machin 2010

ファイルの先頭でメモ帳がBOMをスタックしていることを確認しましたが、Excel 2003 SP2(SP3が利用可能です)を使用しているため、これはSP3でのみ機能すると思います
Cocowalla

2

拡張子が 'xls'のHTMLファイルを保存すると、アクセント記号が機能します(少なくとも2007年以前)。

例:これを(メモ帳でSave utf8を使用して)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>

興味深いオプション。それはテキストを右に開きますが、何らかの理由ですべてのページが完全に白いです。行と列を区切る従来のスプレッドシート行なし(Macのオフィス)
Sebastian Sastre

はい、WindowsのOffice 2007でも同じです。正直に言うと、それがまったく機能したことにはいつも驚かされます。(border="1"テーブルに追加すると、行が表示されます、4つのセルの周りのみです。)
Benjol

1

これは文字エンコーディングの問題です。データをUTF-8としてエクスポートしているようです。UTF-8のéは2バイトのシーケンス0xC3 0xA9であり、Windows-1252で解釈するとéです。データをExcelにインポートするときは、使用している文字エンコードがUTF-8であることを必ず伝えてください。


データがUTF-8であることを確認しました。私はExcelが私のデータがUTF-8(?BOM)であることを知っているように、ファイルの中に何を入れます
Freddo411

ファイルエンコーディングを変更する必要があると思います
。Excel

現在使用しているマシンにExcelがインストールされていないため、完全にはわかりませんが、OpenOfficeでは、CSVファイルをインポートするときに文字エンコードのドロップダウンボックスがあります。そこから、Unicode(UTF-8)を選択します。
Adam Rosenfield、

ExcelにはドロップダウンAFAIKがありません
albertein

1

CSV形式はExcelでUnicodeではなくASCIIとして実装されているため、発音区別符号を扱いません。私は、公式のCSV標準がExcelでASCIIベースであると定義されているという同じ問題を経験しました。


実際、CSVは特定のエンコーディングにバインドされていません。ASCIIを想定しているのはExcelです。 en.wikipedia.org/wiki/Comma-separated_values
スポールソン2009

それは私が言ったことです。「ExcelでASCIIとして実装」、「ExcelでASCIIベースとして定義されたCSV」。あなたが私に同意しているように見えるので、あなたが何を言っているのかわかりません。
ジェフイエーツ

2
実際、「CSV形式はASCIとして実装されている」とおっしゃっていますが、そこが混乱の元です。
RichardOD 2009年

1

Excel 2007は、BOM(EF BB BF)でエンコードされたcsvでUTF-8を適切に読み取ります。

Excel 2003(およびおそらく以前のバージョン)では、BOM(FF FE)を使用してUTF-16LEを読み取りますが、コンマやセミコロンの代わりにTABを使用します。



1

BOMを出力CSVファイルに書き込むと、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

詳細についてはhttp://crashcoursing.blogspot.com/2011/05/exporting-csv-with-special-characters.htmlみんなありがとう!


はい、これはExcel 2010で私にとってうまくいきました。Javaを使用する場合はprintWriter.print('\ufeff')、JavaでUTF-8 BOMを追加する方法も参照してください。
tsauerwein '21 / 09/21

1

私が見つけた別の解決策は、結果をWindowsコードページ1252(Windows-1252またはCP1252)としてエンコードすることでした。これは、たとえば、Content-Type適切にtext/csv; charset=Windows-1252設定し、同様に応答ストリームの文字エンコーディングを設定することによって行われます。


これをありがとう。ExcelのWindowsとMacで動作します。使っています。
セバスチャンサストレ

これは、非ASCII文字の範囲が完全にWindows-1252に該当する場合にのみ機能します。したがって、たとえば、韓国語/中国語/日本語、キリル文字などはありません。しかし、ほとんどの西ヨーロッパ言語では、これでうまくいくと思います。
Tom McClure、

1

UTF-8 BOMを含めることは必ずしも良い考えではないことに注意してください-ExcelのMacバージョンはそれを無視し、実際にBOMをASCIIとして表示します…スプレッドシートの最初のフィールドの先頭に3つの厄介な文字…


私はこのコメントが6年後であることを知っていますが、FWIW:JavaScriptを使用'\uFEFF' + myCsvStringしてMac Excel 15.19.1(2016)で期待どおりに動作するようにファイルをダウンロードします。
bobjones

0

ファイルを生成しているエンコーディングを確認してください。Excelでファイルを正しく表示するには、システムのデフォルトコードページを使用する必要があります。

どの言語を使用していますか?.Netの場合は、ファイルの生成中にEncoding.Defaultを使用するだけで済みます。


エクスポートデータはutf-8です。私はphp 5でエクスポートファイルを書いています
Freddo411

データをWindows-1252コードページにトランスコードします。phpでそれを達成する方法がわかりません
albertein

0

私と同じようにvb.netにレガシーコードがある場合、次のコードがうまくいきました。

    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

私は問題を解決する方法を見つけました。これは厄介なハックですが、機能します。OpenOfficeでドキュメントを開き、Excel形式で保存します。結果の.xlsor .xlsxはアクセント付き文字を表示します。


1
OPは、プログラムでエクスポートしているため、手動による介入が必要なソリューションを探していないと述べています。
Christiaan Westerbeek 2013

0

Ruby 1.8.7では、すべてのフィールドをUTF-16にエンコードし、BOMを破棄します(たぶん)。

次のコードは、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 -%>

重要な行は次のとおりです。

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

-2

Encodeでファイルcsvをnotepad ++ clicで開き、UTF-8に変換する(UTF-8に変換しない(BOMなし))を選択します。クリストフ・グリソンに役立つExcel Hopeでダブルクリックで開く


1
プログラムで行うことになっているため、これは質問に答えません。手動ですべてのファイルを再保存するためにユーザーの介入を必要としません
Joe W
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.