web-dev-qa-db-ja.com

Excelが正常に読み取るUTF-8 CSVをPHPに出力するにはどうすればよいですか。

私はCSV形式でいくつかのものを出力するだけのこの非常に単純なことを持っていますが、それはUTF-8になるはずです。このファイルをTextEdit、TextMate、またはDreamweaverで開くと、UTF-8文字が正しく表示されますが、Excelで開くと、これはばかげたことです。これが私の文書の先頭にあるものです。

header("content-type:application/csv;charset=UTF-8");
header("Content-Disposition:attachment;filename=\"CHS.csv\"");

Excel(Mac、2008)が正しくインポートしたくない場合を除いて、これはすべて望ましい効果があるようです。 Excelには「UTF-8として開く」など何も選択肢がないので、ちょっと面倒になります。

多くの人が同じ問題を抱えているにもかかわらず、私はどこにでもこれに対する明確な解決策を見つけることができないようです。私が最もよく見ているのはBOMを含めることですが、その方法を正確に把握することはできません。あなたが上で見ることができるように、私はちょうどこのデータをechoにしている、私は少しのファイルも書いていない。必要に応じてそれを行うことができますが、現時点ではそれが必要であるとは思われないためではありません。何か手助け?

更新:私はBOMをecho pack("CCC", 0xef, 0xbb, 0xbf);としてエコーしようとしましたが、これはBOMを検出しようとしていたサイトから取り出したものです。しかし、Excelはインポート時に最初のセルにこれらの3文字を追加するだけで、特殊文字をめちゃくちゃにします。

174
Ben Saufley

引用すると マイクロソフトのサポートエンジニア

Excel for Macは現在UTF-8をサポートしていません

更新、2017:これは Office 2016 より前のすべてのバージョンのMicrosoft Excel for Macに当てはまります。新しいバージョン(Office 365以降)は現在UTF-8をサポートしています。

WindowsとOS Xの両方でExcelが正常に読むことができるUTF-8コンテンツを出力するためには、2つのことをする必要があります:

  1. 必ずUTF-8テキストをUTF-16LEに変換してください。

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
  2. 必ずUTF-16LEバイトオーダーマークを付けてください。

    chr(255) . chr(254)
    

OS X上のExcelでのみ発生する次の問題(ただし not Windows)は、CSVファイルをカンマで区切って表示すると、Excelは1行のみですべての行を表示します。最初の行のテキストとカンマ。

これを回避する方法は、タブを区切り値として使用することです。

私は PHP comments (カンマの代わりにタブ "\ t"を使用)からこの関数を使用しましたが、それはOS XとWindows Excelで完璧に動作しました。

行末に空の列があるという問題を修正するには、次のようにコード行を変更する必要があります。

    $field_cnt = count($fields);

    $field_cnt = count($fields)-1;

このページに関する他のコメントの一部が言うように、OpenOffice Calc、Apple自身のNumbers、そしてGoogle DocのSpreadsheetのような他のスプレッドシートアプリケーションは、コンマ付きのUTF-8ファイルに問題がない。

ExcelのUnicode CSVファイルで何が機能するかどうかについては、 この質問の表 を参照してください。


ちなみに、 Composer を使っているのであれば、 League\Csv をrequireに追加してみるのがよいでしょう。 League\CsvCSVファイルを構築するための本当に素晴らしいAPI です。

CSVファイルを作成するこの方法でLeague\Csvを使用するには、チェックアウトしてください この例

125
Tim Groeneveld

私は同じ(または類似の)問題を抱えています。

私の場合は、BOMを出力に追加すればうまくいきます。

header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename=Customers_Export.csv');
echo "\xEF\xBB\xBF"; // UTF-8 BOM

これはかなり醜いハックだと思いますが、私にとっては、少なくともExcel 2007 Windowsではうまくいきました。それがMac上で動作するかどうかわからない。

261
Daniel Magliola

これが私のやり方です(これはcsvファイルをダウンロードするようにブラウザに促すことです):

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=file.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
echo "\xEF\xBB\xBF"; // UTF-8 BOM
echo $csv_file_content;
exit();

Macでスペースバーを押したときのCSVプレビューでのUTF8エンコーディングの問題を修正した唯一のもの。Excel Mac 2008ではそうではありません。

30
Jazzer

私はちょうど同じ問題に対処し、そして2つの解決策を思いついた。

  1. PHPExcel クラス bpeterson76が推奨 を使用してください。

    • このクラスを使用すると、最も広く互換性のあるファイルが生成され、Excel 2008 Mac、Excel 2007 Windows、およびGoogle Docsで正常に開かれたUTF-8エンコードデータからファイルを生成できました。
    • PHPExcelを使用する際の最大の問題は、速度が遅く、多くのメモリを使用することです。これは、適切なサイズのファイルでは問題ありませんが、Excel/CSVファイルに数百または数千の行がある場合はこのライブラリは使用できなくなります
    • TSVデータを取得してブラウザにExcelファイルを出力するPHPメソッドがあります。Excel5Writerを使用していることに注意してください。つまり、ファイルは古いバージョンのExcelと互換性があるはずです。アクセス権がなくなったので、テストできません。

      function Excel_export($tsv_data, $filename) {
          $export_data = preg_split("/\n/", $tsv_data);
          foreach($export_data as &$row) {
              $row = preg_split("/\t/", $row);
          }
      
          include("includes/PHPExcel.php");
          include('includes/PHPExcel/Writer/Excel5.php');
      
          $objPHPExcel = new PHPExcel();          
      
          $objPHPExcel->setActiveSheetIndex(0);
          $sheet = $objPHPExcel->getActiveSheet();
          $row = '1';
          $col = "A";
          foreach($export_data as $row_cells) {
              if(!is_array($row_cells)) { continue; }
                  foreach($row_cells as $cell) {
                      $sheet->setCellValue($col.$row, $cell);
                      $col++;
                  }
              $row += 1;
              $col = "A";
          }
      
          $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel);
          header('Content-Type: application/vnd.ms-Excel');
          header('Content-Disposition: attachment;filename="'.$filename.'.xls"');
          header('Cache-Control: max-age=0');
          $objWriter->save('php://output');   
          exit;   
      }
      
  2. PHPExcelの効率の問題のために、私はまたどのようにUTF-8とExcelと互換性のあるCSVまたはTSVファイルを生成するかを考え出さなければなりませんでした。

    • 私が考え出すことができた最高のものは、Excel 2008 MacとExcel 2007 PCと互換性があるが、Google Docsは互換性がないファイルでした、それは私のアプリケーションにとって十分に良いです。
    • 私はその解決策を見つけました ここで 、具体的には この答え ですが、問題を説明しているので 受け入れられた答え も読むべきです。
    • これが私が使用したPHPコードです、私はtsvデータを使用していることに注意してください(コンマの代わりに区切り文字としてタブ):

      header ( 'HTTP/1.1 200 OK' );
      header ( 'Date: ' . date ( 'D M j G:i:s T Y' ) );
      header ( 'Last-Modified: ' . date ( 'D M j G:i:s T Y' ) );
      header ( 'Content-Type: application/vnd.ms-Excel') ;
      header ( 'Content-Disposition: attachment;filename=export.csv' );
      print chr(255) . chr(254) . mb_convert_encoding($tsv_data, 'UTF-16LE', 'UTF-8');
      exit;
      
22
Jasdeep Gosal

私は同じ問題を抱えていて、それは以下のように解決されました:

    header('Content-Encoding: UTF-8');
    header('Content-Type: text/csv; charset=utf-8' );
    header(sprintf( 'Content-Disposition: attachment; filename=my-csv-%s.csv', date( 'dmY-His' ) ) );
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');

    $df = fopen( 'php://output', 'w' );

    //This line is important:
    fputs( $df, "\xEF\xBB\xBF" ); // UTF-8 BOM !!!!!

    foreach ( $rows as $row ) {
        fputcsv( $df, $row );
    }
    fclose($df);
    exit();
13
Reza Mamun

ExcelはUTF-8をサポートしません。 UTF-8テキストをUCS-2LEにエンコードする必要があります。

mb_convert_encoding($output, 'UCS-2LE', 'UTF-8');
12
Leopold Gault

これをフォローアップするには:

問題は単にMac上のExcelにあるようです。それは私がファイルを生成する方法ではありません、なぜならCSVを生成することさえExcelからはそれらを壊しています。 CSVとして保存して再インポートすると、すべての文字がめちゃくちゃになります。

それで…これに対する正しい答えはないようです。すべての提案をありがとう。

私が読んだことのすべてから、BOMについての@Daniel Magliolaの提案はおそらく他のコンピュータにとって最良の答えになるでしょう。しかし、それでもまだ私の問題は解決しません。

8
Ben Saufley

これは、WindowsとMac OSの両方のExcelで正常に機能します。

発音区別符号、キリル文字、ギリシャ文字、および通貨記号を含む文字が表示されないというExcelの問題を修正しました。

function writeCSV($filename, $headings, $data) {   

    //Use tab as field separator
    $newTab  = "\t";
    $newLine  = "\n";

    $fputcsv  =  count($headings) ? '"'. implode('"'.$newTab.'"', $headings).'"'.$newLine : '';

    // Loop over the * to export
    if (! empty($data)) {
      foreach($data as $item) {
        $fputcsv .= '"'. implode('"'.$newTab.'"', $item).'"'.$newLine;
      }
    }

    //Convert CSV to UTF-16
    $encoded_csv = mb_convert_encoding($fputcsv, 'UTF-16LE', 'UTF-8');

    // Output CSV-specific headers
    header('Set-Cookie: fileDownload=true; path=/'); //This cookie is needed in order to trigger the success window.
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$filename.csv\";" );
    header("Content-Transfer-Encoding: binary");
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/Excel

    exit;
}
7
Murali Krishna

私の場合、次のように動作します。UTF-8文字のCSVファイルをExcelで正しく表示できるようになりました。

$out = fopen('php://output', 'w');
fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($out, $some_csv_strings);

0xEF 0xBB 0xBF BOMヘッダーはExcelに正しいエンコーディングを知らせます。

6
Codemole

CSVファイルのマスストには、バイトオーダーマークが含まれています。

または提案されたそして回避策としてHTTPボディとそれを単にエコーして下さい

6
Cybot

UTF8エンコーディングはExcelではうまく動作しません。 iconv()を使って、データを他のエンコーディングタイプに変換することができます。

例えば.

iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),
4

追加:

fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));

または

fprintf($file, "\xEF\xBB\xBF");

CSVファイルに内容を書き込む前に。

例:

<?php
$file = fopen( "file.csv", "w");
fprintf( $file, "\xEF\xBB\xBF");
fputcsv( $file, ["english", 122, "বাংলা"]);
fclose($file);
4
Rejaul
**This is 100% works fine in Excel for both Windows7,8,10 and also All Mac OS.**
//Fix issues in Excel that are not displaying characters containing diacritics, cyrillic letters, Greek letter and currency symbols.

function generateCSVFile($filename, $headings, $data) {

    //Use tab as field separator
    $newTab  = "\t";
    $newLine  = "\n";

    $fputcsv  =  count($headings) ? '"'. implode('"'.$newTab.'"', $headings).'"'.$newLine : '';

    // Loop over the * to export
    if (! empty($data)) {
      foreach($data as $item) {
        $fputcsv .= '"'. implode('"'.$newTab.'"', $item).'"'.$newLine;
      }
    }

    //Convert CSV to UTF-16
    $encoded_csv = mb_convert_encoding($fputcsv, 'UTF-16LE', 'UTF-8');

    // Output CSV-specific headers
    header('Set-Cookie: fileDownload=true; path=/'); //This cookie is needed in order to trigger the success window.
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$filename.csv\";" );
    header("Content-Transfer-Encoding: binary");
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/Excel
    exit;
}
2
Sagar72427

mb_convert_encodingを使用してすでにUTF-8でエンコードされたテキストを変換する必要はありません。元のコンテンツの前に3文字を追加するだけです。

$newContent = chr(239) . chr(187) . chr(191) . $originalContent

私にとってはこれでcsvファイルの特殊文字の問題は解決しました。

2
Rvanlaak

私が調べたところ、UTF-8はMACとWindowsではうまく動かないことがわかったので、Windows-1252で試したところ、両方でうまくサポートされていますが、あなたはubuntuでエンコーディングのタイプを選択する必要があります。これが私のcode$valueToWrite = mb_convert_encoding($value, 'Windows-1252');です。

$response->headers->set('Content-Type', $mime . '; charset=Windows-1252');
    $response->headers->set('Pragma', 'public');
    $response->headers->set('Content-Endcoding','Windows-1252');
    $response->headers->set('Cache-Control', 'maxage=1');
    $response->headers->set('Content-Disposition', $dispositionHeader);
    echo "\xEF\xBB\xBF"; // UTF-8 BOM
2
Ho Ha

私にとっては上記の解決策はどれもうまくいきませんでした。以下は私が問題を解決するためにしたことです:PHPコードでこの機能を使って値を修正してください:

$value = utf8_encode($value);

この値はExcelシートで正しく出力されます。

1
Barani r

あなたはエンコーディング "Windows-1252"を使わなければなりません。

header('Content-Encoding: Windows-1252');
header('Content-type: text/csv; charset=Windows-1252');
header("Content-Disposition: attachment; filename={$filename}");

たぶんあなたはあなたの文字列を変換する必要があります:

private function convertToWindowsCharset($string) {
  $encoding = mb_detect_encoding($string);

  return iconv($encoding, "Windows-1252", $string);
}
1
roNn23

Excel自体に出力するだけではどうでしょうか。 これは優れたクラスです サーバーサイドでXLSファイルを生成することを可能にします。私はcsvを「理解する」ことができず、これまで苦情を抱えたことが一度もなかったクライアントのためにそれを頻繁に使います。それはまたcsvが決してしないいくつかの余分なフォーマット(シェーディング、行の高さ、計算など)を可能にします。

1
bpeterson76

cSV文字列はiconvで変換できます。例えば:

$csvString = "Möckmühl;in Möckmühl ist die Hölle los\n";
file_put_contents('path/newTest.csv',iconv("UTF-8", "ISO-8859-1//TRANSLIT",$csvString) );
1
foued611

私はMacを使っています。私の場合は"sep=;\n"で区切り文字を指定し、ファイルを次のようにUTF-16LEでエンコードするだけでした。

$data = "sep=;\n" .mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');
1
Sebastien Horin

あなたはエクスポートする前にファイルに3バイトを追加することができます、それは私のために働きます。そのシステムを実行する前は、WindowsとHP -UXでしか機能しませんでしたが、Linuxでは機能しませんでした。

FileOutputStream fStream = new FileOutputStream( f );
final byte[] bom = new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
OutputStreamWriter writer = new OutputStreamWriter( fStream, "UTF8" );
fStream.write( bom );

ファイルの先頭にUTF-8 BOM(3バイト、16進数EF BB BF)があります。そうでなければ、Excelはutf-8の代わりにあなたのロケールのデフォルトエンコーディング(例えばcp1252)に従ってデータを解釈します。

Excel用CSVファイルの生成、値の中に改行を入れる方法

1
Cherry Yap

#はExcelが正しく読むことができるようにPHPにUTF-8 CSVを出力します。

//Use tab as field separator   
$sep  = "\t";  
$eol  = "\n";    
$fputcsv  =  count($headings) ? '"'. implode('"'.$sep.'"', $headings).'"'.$eol : '';
0
Murali Krishna

私はこれを使います

header('Content-Description: File Transfer');
header('Content-Type: text/csv; charset=UTF-16LE');
header('Content-Disposition: attachment; filename=file.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
// output headers so that the file is downloaded rather than displayed
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
fputs( $output, "\xEF\xBB\xBF" );
// output the column headings
fputcsv($output, array('Thông tin khách hàng đăng ký'));
// fetch the data
$setutf8 = "SET NAMES utf8";
$q = $conn->query($setutf8);
$setutf8c = "SET character_set_results = 'utf8', character_set_client =
'utf8', character_set_connection = 'utf8', character_set_database = 'utf8',
character_set_server = 'utf8'";
$qc = $conn->query($setutf8c);
$setutf9 = "SET CHARACTER SET utf8";
$q1 = $conn->query($setutf9);
$setutf7 = "SET COLLATION_CONNECTION = 'utf8_general_ci'";
$q2 = $conn->query($setutf7);
$sql = "SELECT id, name, email FROM myguests";
$rows = $conn->query($sql);
$arr1= array();
if ($rows->num_rows > 0) {
// output data of each row
while($row = $rows->fetch_assoc()) {
    $rcontent = " Name: " . $row["name"]. " - Email: " . $row["email"];  
    $arr1[]["title"] =  $rcontent;
}
} else {
     echo "0 results";
}
$conn->close();
// loop over the rows, outputting them
foreach($arr1 as $result1):
   fputcsv($output, $result1);
endforeach;
0
BoRnbeBaD

Mac Excel 2008のための簡単な解決策:私はこれで何度も苦労しましたが、ここに私の簡単な修正がありました:あなたのUTF-8文字を正しく開くはずのTextwranglerで.csvファイルを開きます。一番下のステータスバーで、ファイル形式を「Unicode(UTF-8)」から「Western(ISO Latin 1)」に変更し、ファイルを保存します。今すぐあなたのMac Excel 2008に行き、File> Import> csvの選択>あなたのファイルの検索> File Originの中で "Windows(ANSI)"を選ぶとUTF-8文字が正しく表示されます。少なくともそれは私のために...

0
Poul

データをインポートするExcel VBAルーチンがあったときにも同じ問題がありました。 CSVはプレーンテキスト形式なので、ワードパッドのような単純なファイルエディタでプログラム的にデータを開き、それをUnicodeテキストとして再保存するか、そこからクリップボードにコピーしてExcelに貼り付けることで、この問題を回避しました。 Excelが自動的にCSVをセルに解析しない場合は、組み込みの「テキストから列へ」機能を使用して簡単に解決できます。

0
Alain

これらのヘッダーを試してみたところ、Windows 7 PC上のExcel 2013で特殊文字を含むCSVファイルを正しくインポートできました。 Byte Order Mark(BOM)がそれを機能させる最後の鍵でした。

 
 header( 'Content-Encoding:UTF-8'); 
 header( 'コンテンツタイプ:text/csv;文字セット= UTF-8'); 
 header( "Content-disposition:attachment; filename = filename.csv"); 
 header( "プラグマ:public"); 
 header( "Expires:0"); [.____ echo "\ xEF\xBB\xBF"; // UTF-8 BOM 
 
0
Brian

それ以外の場合は

header("Content-type: application/x-download");
header("Content-Transfer-Encoding: binary");
header("Content-disposition: attachment; filename=".$fileName."");
header("Cache-control: private");

echo utf8_decode($output);
0
user3519396

あなたがそれを.txtファイルとして保存して、それらが区切り文字としてカンマでそれをExcelで開くとき、問題はまだ起こりますか?

問題はまったくエンコーディングではないかもしれません、それはただファイルがExcel標準に従って完全なCSVではないということかもしれません。

0
Alain

この投稿はかなり古くなっていますが、何時間もかけて自分の解決策を共有したいと思います...おそらくExcelやMac、CSVを扱う人を助け、この脅威についてつまずくことになります。私はExcelユーザーを念頭に置いてデータベースからの出力としてcsvを動的に生成しています。 (BOM付きUTF-8)

私はたくさんのiconvを試したが、ドイツ語のウムラウトをMac Excel 2004で動かすことができなかった。一つの解決策:PHPExcel。それは素晴らしいことですが、私のプロジェクトにとっては少しやり過ぎです。私にとってうまくいくのは、csvファイルを作成し、このPHPスニペットを使用してこのcsvファイルをxlsに変換することです。 csv2xls 。結果xlsはExcelのドイツ語ウムラウト(ä、ö、Ü、...)で機能します。

0
t Book