質問

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

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

これをテキスト エディタ (UltraEdit) で開くことができ、正しく表示されます。UE によると、そのキャラクターは decimal 233.

どうやって テキストをエクスポートする データは .csv ファイルにあるので、 MS Excel が正しくレンダリングすること できればインポート ウィザードの使用を強制したり、デフォルト以外のウィザード設定を使用したりしないでください。

役に立ちましたか?

解決

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

Excelは、ファイルの関連付けを介してUTF8 CSVファイルを開くと、UTF8 BOMの存在を無視してシングルバイトエンコーディングであると想定するという既知のバグがあります。これは、システムのデフォルトのコードページまたは言語設定によって修正することはできません。 BOMはExcelで手掛かりになりません-動作しません。 (少数レポートでは、BOMが<!> quot; Import Text <!> quot;ウィザードをトリガーすることがあると主張しています。)このバグはExcel 2003以前に存在するようです。ほとんどのレポート(ここの回答の中)では、これはExcel 2007以降で修正されていると述べています。

<!> quot; Import Text <!> quot;を使用して、ExcelでUTF-8 CSVファイルを常に *常に正しく開くことができます。ウィザード。開いているファイルのエンコーディングを指定できます。もちろん、これはあまり便利ではありません。

この回答の読者は、Excelを特にサポートしていない状況である可能性が最も高い<!> lt; 2007が、未加工のUTF8テキストをExcelに送信していますが、これはテキストを誤って解釈し、テキストにÃおよび他の同様のWindows-1252文字を振りかけています。 UTF8 BOMを追加するのがおそらく最良かつ迅速な修正方法です。

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


*できない場合を除いて、(少なくとも)Excel 2011 for Macのインポートウィザードは、実際にすべてのエンコードで動作するとは限りません。 <!> lt; /逸話証拠<!> gt; :)

他のヒント

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

以下は、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に感謝します。

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

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

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

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

  • エンコード
  • BOMキャラクターの存在
  • セル区切り

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

信じられない?どちらもしませんが、ここを読んで泣いてください: http://wiki.sdn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator

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

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

echo "\xEF\xBB\xBF";

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

UTF-8は、BOMの有無にかかわらず、サービスパックなしでOffice 2007で動作しません (U + ffefまたは0xEF、0xBB、0xBF、どちらも機能しません) 0xEF、0xBB、0xBF BOMが付加されている場合、sp3をインストールするとUTF-8が機能します。

UTF-16は、Pythonで<!> quot; utf-16-le <!> quot;を使用してエンコードするときに機能します。 0xff 0xefで BOMが先頭に追加され、タブをセパレータとして使用します。 BOMを手動で書き出してから、<!> quot; utf-16-le <!> quot;を使用する必要がありました。むしろ<!> quot; utf-16 <!> quot ;, それ以外の場合、各encode()は、書き込まれたすべての行にBOMを追加します 2行目以降の最初の列にゴミとして表示されました。

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

これはWindowsにあり、MACのオフィスについてはわかりません。

両方の作業ケースで、ダウンロードを直接起動するときにインポートが機能します ブラウザとテキストインポートウィザードは機能しません。期待どおりに動作します。

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

質問が<!> quot; answer <!> quot;であることにも気付きました。しばらく前ですが、テキストウィザードを使用しないとExcelでutf8でエンコードされたcsvファイルを正常に開けないという話はわかりません。

私の再現可能な経験: 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エクスプローラーを開き、ファイル名をダブルクリックするか、右クリックして<!> quot; Open with ... <!> quot;を使用すると、期待どおりにExcel(2003)がポップアップ表示されます。

拡張子が「xls」のhtmlファイルを保存でき、アクセントが機能します(少なくとも2007年以前)。

例:これを(メモ帳で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>

これは文字エンコーディングの問題です。データをUTF-8としてエクスポートしているように見えます:<!>#233; UTF-8の2バイトシーケンス0xC3 0xA9は、Windows-1252で解釈されると<!>#195; <!>#169;です。データをExcelにインポートするときは、使用している文字エンコードがUTF-8であることを必ず確認してください。

CSV形式は、ユニコードではなくASCIIとしてExcelに実装されているため、発音区別符号がマングリングされます。公式のCSV標準がExcelでASCIIベースであると定義されていることを突き止めたのと同じ問題を経験しました。

出力CSVファイルへのBOMの書き込みは、実際に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 ありがとうございます!

別の解決策は、結果をWindowsコードページ1252(Windows-1252またはCP1252)としてエンコードすることでした。これは、たとえばContent-Typetext/csv; charset=Windows-1252などに適切に設定し、同様に応答ストリームの文字エンコードを設定することで実行されます。

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

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

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

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

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

適切なバイトオーダーマークで始まるタブ区切りのリトルエンディアンUTF-16として、Excel 2007でCSVを適切に解析することしかできません。

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

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

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]

notepad ++でcsvファイルを開きます Encodeでクリック、UTF-8への変換を選択(UTF-8に変換しない(BOMなし)) 保存する Excelでダブルクリックで開きます その助けを願っています クリストフ・グリソン

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top