byte-order-mark 다운로드 - Excel에서 올바르게 읽는 PHP에서 UTF-8 CSV를 출력하려면 어떻게합니까?




header content (25)

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을 포함하는 것입니다.하지만이를 수행하는 방법을 정확히 파악할 수는 없습니다. 위에서 볼 수 있듯이이 데이터를 보내고있는 중이며 파일을 쓰지 않습니다. 필요한 경우이를 수행 할 수 있습니다. 현재로서는 필요가없는 것처럼 보이기 때문에 아닙니다. 어떤 도움이 필요합니까?

업데이트 : BOM을 echo pack("CCC", 0xef, 0xbb, 0xbf); 으로 echo pack("CCC", 0xef, 0xbb, 0xbf); BOM을 감지하려고 시도한 사이트에서 방금 가져 왔습니다. 그러나 Excel은 수입시 첫 번째 셀에이 세 문자를 추가하고 여전히 특수 문자를 엉망으로 만듭니다.


Answers

내가 조사한 결과, 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

나는 (또는 이와 유사한) 동일한 문제가있다.

내 경우 출력에 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에서 작동하는지 확신하지 못합니다.


Excel 자체를 출력하는 것은 어떨까요? 이것은 XLS 파일을 서버 측에서 생성 할 수 있는 훌륭한 클래스 입니다. 나는 csv를 "알아낼"수없고 지금까지 불평이 없었던 고객을 위해 그것을 자주 사용합니다. 또한 csv가 수행하지 않는 몇 가지 추가 서식 (음영, 행렬, 계산 등)을 허용합니다.


더하다:

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

방금 이러한 헤더를 시도하고 Windows 7 PC에서 Excel 2013을 사용하여 특수 문자로 CSV 파일을 올바르게 가져 왔습니다. Byte Order Mark (BOM)가 작동하게 한 최종 키입니다.

    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


나를 위해 위의 해결 방법 중 아무 것도 작동하지 않았습니다. 아래는이 문제를 해결하기 위해 수행 한 작업입니다. PHP 코드에서이 함수를 사용하여 값을 수정하십시오.

$value = utf8_encode($value);

이 출력은 엑셀 시트에서 적절하게 표시됩니다.


.txt 파일로 저장할 때 문제가 계속 발생하며 쉼표로 구분 기호로 Excel에서 열 때 문제가 발생합니까?

문제는 인코딩이 아닐 수도 있습니다. 파일이 Excel 표준에 따라 완벽한 CSV가 아닐 수도 있습니다.


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

난 그냥 같은 문제를 처리하고 두 가지 해결책을 생각해 냈습니다.

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

    • 이 클래스를 사용하면 가장 널리 호환되는 파일을 생성하므로 Excel 2008 Mac, Excel 2007 Windows 및 Google Docs에서 열리는 UTF-8 인코딩 데이터로 파일을 생성 할 수있었습니다.
    • PHPExcel을 사용할 때의 가장 큰 문제점은 속도가 느리고 합리적인 크기의 파일에서는 문제가되지 않는 많은 메모리를 사용하지만 Excel / CSV 파일에 수백 또는 수천 개의 행이 있으면이 라이브러리를 사용할 수 없게된다는 것 입니다.
    • 다음은 몇 가지 TSV 데이터를 가져와 브라우저로 Excel 파일을 출력하는 PHP 메소드입니다. Excel5 Writer를 사용한다는 점에 유의하십시오. 이는 파일이 이전 버전의 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 문서 도구는 아니었기 때문에 내 응용 프로그램에 충분히 적합했습니다.
    • here 해결책, 특히이 대답을 찾았지만, 문제를 설명 할 때 수용된 대답 도 읽어야합니다.
    • 다음은 내가 사용한 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;
      

여기 내가 어떻게했는지 (브라우저에 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에서는 그렇지 않습니다 ... 이유를 모릅니다.


데이터를 가져온 Excel VBA 루틴이있을 때도 이와 동일한 문제가있었습니다. CSV는 일반 텍스트 형식이므로 워드 패드와 같은 간단한 파일 편집기에서 프로그래밍 방식으로 데이터를 열고 유니 코드 텍스트로 다시 저장하거나 클립 보드에 복사하여 Excel에 붙여서이 문제를 해결하려고했습니다. Excel이 자동으로 CSV를 셀로 구문 분석하지 않으면 내장 된 "텍스트와 열"기능을 사용하여 쉽게 해결할 수 있습니다.


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

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

Mac Excel 2008의 간편한 솔루션 : 여러 번 어려움을 겪었으나 Texturerangler에서 .csv 파일을 열면 UTF-8 문자가 올바르게 열립니다. 이제 하단 상태 표시 줄에서 "유니 코드 (UTF-8)"에서 "Western (ISO Latin 1)"으로 파일 형식을 변경하고 파일을 저장하십시오. 이제 Mac Excel 2008로 이동하여 파일> 가져 오기> csv> 파일 찾기> 파일 원본에서 "Windows (ANSI)"를 선택하고 UTF-8 문자가 올바르게 표시되는지 확인하십시오. 적어도 그것은 나를 위해 ...


내 경우에는 다음 작품은 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에서 올바른 인코딩을 알 수 있습니다.


내보내기 전에 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 파일 생성, 값 내에서 개행을 사용하는 방법


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

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

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

이것은 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;
}

그렇지 않으면 다음을 할 수 있습니다.

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

CSV 파일에는 바이트 순서 표가 포함되어 있습니다.

아니면 제안 및 해결 방법으로 그냥 HTTP 본문으로 에코


인코딩 "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);
}

iconv 로 CSV 문자열을 변환 할 수 있습니다. 예 :

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

Microsoft 기술 지원 엔지니어 를 인용하려면,

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)
    

쉼표로 구분 된 값으로 된 CSV 파일을 볼 때 Excel은 한 행만있는 행과 모든 텍스트를 첫 행의 쉼표와 함께 렌더링합니다.

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

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

비어있는 열의 문제를 행의 끝으로 수정하려면 다음 코드 행을 변경해야합니다.

    $field_cnt = count($fields);

    $field_cnt = count($fields)-1;

이 페이지의 다른 의견에 따르면 OpenOffice Calc, Apple의 Numbers 및 Google Doc의 스프레드 시트와 같은 다른 스프레드 시트 응용 프로그램은 쉼표가있는 UTF-8 파일에는 문제가 없습니다.

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

참고로 Composer 를 사용하는 경우 League\Csv 를 요구 사항에 추가해야합니다. League\Csv 에는 CSV 파일을 작성하기위한 정말 멋진 API가 있습니다 .

CSV 파일을 만드는이 방법으로 League\Csv 를 사용하려면 이 예제를 확인하십시오.


나는 Mac에 있는데, 제 경우에는 "sep=;\n" 구분 기호를 지정하고 파일을 UTF-16LE로 다음과 같이 인코딩해야합니다.

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





php csv utf-8 byte-order-mark