Programing

Excel에서 올바르게 읽을 수 있도록 PHP에서 UTF-8 CSV를 출력하려면 어떻게해야합니까?

crosscheck 2020. 5. 18. 21:55
반응형

Excel에서 올바르게 읽을 수 있도록 PHP에서 UTF-8 CSV를 출력하려면 어떻게해야합니까?


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은 이러한 세 문자를 가져올 때 첫 번째 셀에 추가하고 특수 문자를 엉망으로 만듭니다.


인용 마이크로 소프트 지원 엔지니어 ,

Mac 용 Excel은 현재 UTF-8을 지원하지 않습니다

2017 년 업데이트 : Office 2016 이전의 모든 Mac 용 Microsoft Excel 버전에 해당 됩니다. Office 365의 최신 버전은 이제 UTF-8을 지원합니다.

Windows 및 OS X 모두에서 Excel에서 읽을 수있는 UTF-8 컨텐츠를 출력하려면 두 가지 작업을 수행해야합니다.

  1. UTF-8 텍스트를 UTF-16LE로 변환하십시오

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
  2. UTF-16LE 바이트 순서 표시를 추가하십시오

    chr(255) . chr(254)
    

단지 OS X에 엑셀 (그러나이 나타납니다 다음 문제 되지 쉼표, Excel에서 하나의 행과 첫 번째 행에서 쉼표와 함께 모든 텍스트와 행을 렌더링 값을 분리하여 CSV 파일을 볼 때 윈도우)입니다.

이를 피하는 방법은 탭을 분리 된 값으로 사용하는 것입니다.

PHP 주석 (쉼표 대신 "\ t"탭 사용) 에서이 기능을 사용했으며 OS X 및 Windows Excel에서 완벽하게 작동했습니다.

행의 끝으로 빈 열의 문제를 해결하려면 다음과 같이 코드 줄을 변경해야했습니다.

    $field_cnt = count($fields);

    $field_cnt = count($fields)-1;

이 페이지의 다른 의견 중 일부에서 알 수 있듯이 Apple의 자체 Numbers 및 Google Doc 's Spreadsheet와 같은 OpenOffice Calc와 같은 다른 스프레드 시트 응용 프로그램에는 쉼표가있는 UTF-8 파일에 문제가 없습니다.

Excel의 유니 코드 CSV 파일에서 작동하는 것과 작동하지 않는 것은 이 질문의 표를 참조하십시오 .


참고로 Composer 를 사용하는 경우 League\Csv요구 사항 에 추가하는 것을 살펴 봐야한다고 덧붙일 수 있습니다 . League\CsvCSV 파일을 구축하기위한 정말 좋은 API를 .

League\Csv이 CSV 파일 작성 방법과 함께 사용하려면 이 예제를 확인하십시오.


나는 같은 (또는 비슷한) 문제가 있습니다.

필자의 경우 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에서 작동하는지 확실하지 않습니다.


다음은 내가 한 방법입니다 (브라우저가 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에서는 그렇지 않습니다 ... 이유를 모릅니다


방금 동일한 문제를 해결하고 두 가지 해결책을 생각해 냈습니다.

  1. bpeterson76 에서 제안한대로 PHPExcel 클래스 사용하십시오 .

    • 이 클래스를 사용하면 가장 광범위하게 호환되는 파일이 생성되므로 Excel 2008 Mac, Excel 2007 Windows 및 Google Docs에서 잘 열린 UTF-8 인코딩 데이터에서 파일을 생성 할 수있었습니다.
    • PHPExcel을 사용할 때 가장 큰 문제는 속도가 느리고 메모리를 많이 사용한다는 것입니다. 합리적인 크기의 파일에는 문제가되지 않지만 Excel / CSV 파일에 수백 또는 수천 개의 행이 있으면이 라이브러리를 사용할 수 없게 됩니다.
    • 다음은 일부 TSV 데이터를 가져 와서 Excel 파일을 브라우저에 출력하는 PHP 메소드입니다. Excel5 기록기를 사용한다는 점에 유의하십시오. 이는 파일이 이전 버전의 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;
      

나는 같은 문제가 있었고 다음과 같이 해결되었습니다.

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

Excel은 UTF-8을 지원하지 않습니다. UTF-8 텍스트를 UCS-2LE로 인코딩해야합니다.

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

이에 대한 후속 조치 :

문제는 Mac의 Excel에서만 발생하는 것으로 보입니다. Excel에서 CSV 생성하더라도 파일이 손상되기 때문에 파일을 생성하는 방식이 아닙니다 . CSV로 저장하고 다시 가져 오면 모든 문자가 엉망입니다.

따라서… 이에 대한 정답은없는 것 같습니다. 모든 제안에 감사드립니다.

필자가 읽은 모든 것에서 BOM에 대한 @Daniel Magliola의 제안은 아마도 다른 컴퓨터에 대한 최선의 대답 일 것입니다. 그러나 여전히 내 문제를 해결하지 못합니다.


필자의 경우 다음은 UTF-8 문자가 포함 된 CSV 파일을 Excel에서 올바르게 표시하는 데 매우 효과적입니다.

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

0xEF 0xBB 0xBFBOM 헤더는 Excel이 올바른 인코딩을 알려드립니다.


이것은 Windows 및 Mac OS 모두에서 잘 작동합니다.

분음 부호, 키릴 문자, 그리스 문자 및 통화 기호가 포함 된 문자를 표시하지 않는 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;
}

CSV 파일은 바이트 순서 표시를 포함해야합니다.

또는 제안 및 해결 방법은 HTTP 본문으로 에코하십시오.


UTF8 인코딩은 Excel에서 잘 작동하지 않기 때문에 을 사용하여 데이터를 다른 인코딩 유형으로 변환 할 수 있습니다 iconv().

예 :

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

더하다:

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

이미 UTF-8로 인코딩 된 텍스트를 사용하여 변환 mb_convert_encoding할 필요는 없습니다. 원본 내용 앞에 세 문자 만 추가하십시오.

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

나를 위해 이것은 CSV 파일의 특수 문자 문제를 해결했습니다.


조사한 결과 UTF-8이 MAC 및 Windows에서 제대로 작동하지 않으므로 Windows-1252로 시도했지만 두 가지 모두에서 잘 지원되지만 우분투에서 인코딩 유형을 선택해야합니다. 여기 내 코드가 있습니다$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

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

How about just outputting for Excel itself? This is an excellent class that allows you to generate XLS files server-side. I use it frequently for clients who can't "figure out" csv's and so far have never had a complaint. It also allows some extra formatting (shading, rowheights, calculations, etc) that csv won't ever do.


you can convert your CSV String with iconv. for example:

$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) );

You have to use the encoding "Windows-1252".

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

Maybe you have to convert your strings:

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

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

You may append the 3 bytes to the file before exporting, it works for me . Before doing that system only work in Windows and HP -UX but failed in 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 );

Have a UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file. Otherwise Excel will interpret the data according to your locale's default encoding (e.g. cp1252) instead of utf-8

Generating CSV file for Excel, how to have a newline inside a value


I'm on Mac, in my case I just had to specify the separator with "sep=;\n" and encode the file in UTF-16LE like this:

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

For me none of the solution above worked. Below is what i did to resolve the issue: modify the value using this function in the PHP code:

$value = utf8_encode($value);

This output values properly in an excel sheet.


I had this same problem when I had an Excel VBA routine that imported data. Since CSV is a plain text format, I was working around this by programatically opening the data in a simple file editor like wordpad, and re-saving it as unicode text, or copying it to the clipboard from there and pasting it to Excel. If excel doesn't automatically parse the CSV into cells, this is easily remedied using the built in "Text to Columns" feature.


Does the problem still occur when you save it as a .txt file and them open that in excel with comma as a delimiter?

The problem might not be the encoding at all, it might just be that the file isn't a perfect CSV according to excel standards.


This Post is quite old, but after hours of trying I want to share my solution … maybe it helps someone dealing with Excel and Mac and CSV and stumbles over this threat. I am generating a csv dynamically as output from a Database with Excel Users in mind. (UTF-8 with BOM)

I tried a lot of iconv´s but couldn´t get german umlauts working in Mac Excel 2004. One solution: PHPExcel. It is great but for my project a bit too much. What works for me is creating the csv file and convert this csv file to xls with this PHPsnippet: csv2xls. the result xls works with excel german umlauts (ä,ö,Ü,...).


I just tried these headers and got Excel 2013 on a Windows 7 PC to import the CSV file with special characters correctly. The Byte Order Mark (BOM) was the final key that made it work.


    header('Content-Encoding: UTF-8');
    header('Content-type: text/csv; charset=UTF-8');
    header("Content-disposition: attachment; filename=filename.csv");
    header("Pragma: public");
    header("Expires: 0");
    echo "\xEF\xBB\xBF"; // UTF-8 BOM


Otherwise you may:

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

EASY solution for Mac Excel 2008: I struggled with this soo many times, but here was my easy fix: Open the .csv file in Textwrangler which should open your UTF-8 chars correctly. Now in the bottom status bar change the file format from "Unicode (UTF-8)" to "Western (ISO Latin 1)" and save the file. Now go to your Mac Excel 2008 and select File > Import > Select csv > Find your file > in File origin select "Windows (ANSI)" and voila the UTF-8 chars are showing correctly. At least it does for me...


I use this and it works

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;

#output a UTF-8 CSV in PHP that Excel will read properly.

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

//convert UTF-8 file without BOM to UTF-16LE for excel on mac
$fileUtf8String = file_get_contents("file.ext");
file_put_contents("file.ext", "\xFF\xFE" . mb_convert_encoding($fileUtf8String, "UTF-16LE", "UTF-8"));

참고URL : https://stackoverflow.com/questions/4348802/how-can-i-output-a-utf-8-csv-in-php-that-excel-will-read-properly

반응형