programing

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

coolbiz 2022. 10. 4. 21:37
반응형

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)이 제대로 Import를 원하지 않는 것을 제외하고는 모두 바람직한 결과를 얻을 수 있을 것 같습니다.Excel에는 UTF-8로 오픈할 수 있는 옵션이 없기 때문에 조금 짜증이 납니다.

많은 사람들이 같은 문제를 겪고 있음에도 불구하고 나는 어디에서도 이에 대한 명확한 해결책을 찾을 수 없을 것 같다.가장 많이 보이는 것은 BOM을 포함하는 것인데, 어떻게 해야 하는지 정확히 알 수 없습니다. 저는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.echo필요하다면 그렇게 할 수 있지만, 지금으로선 그럴 필요가 없어 보여서 그런 게 아니에요.도움이 필요하신가요?

을 "BOM"으로 .echo pack("CCC", 0xef, 0xbb, 0xbf); 흐트러집니다.그러나 Excel은 Import할 때 첫 번째 셀에 이 세 글자를 추가하기만 하면 특수 문자가 계속 흐트러집니다.

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

제 경우 출력에 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에서 작동할지 확실하지 않습니다.

Microsoft 지원 엔지니어의 견적을 내자면,

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

업데이트, 2017:이는 Office 2016 이전 버전의 Mac용 Microsoft Excel에 적용됩니다.새로운 버전(Office 365부터)에서는 UTF-8이 지원되게 되었습니다.

Windows와 OS X 모두에서 Excel이 정상적으로 읽을 수 있는 UTF-8 콘텐츠를 출력하려면 다음 두 가지 작업을 수행해야 합니다.

  1. UTF-8 CSV 텍스트를 UTF-16LE로 변환해 주세요.

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
  2. 파일 시작 부분에 UTF-16LE 바이트 순서 마크를 추가해야 합니다.

    chr(255) . chr(254)
    

OS X(Windows 이외)의 Excel에서만 나타나는 다음 문제는 쉼표로 구분된 값을 가진 CSV 파일을 볼 때 Excel은 첫 번째 행의 쉼표와 함께 하나의 행과 모든 텍스트만 렌더링합니다.

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

PHP 코멘트(쉼표 대신 탭 "\t" 사용)에서 이 기능을 사용했는데 OS X와 Windows Excel에서 완벽하게 작동했습니다.

행의 끝에 빈 열이 있는 문제를 수정하려면 다음과 같은 코드 행을 변경해야 합니다.

    $field_cnt = count($fields);

로.

    $field_cnt = count($fields)-1;

이 페이지의 다른 코멘트 중 일부는 OpenOffice Calc, Apple의 자체 번호 및 Google Doc의 스프레드시트와 같은 다른 스프레드시트 앱은 쉼표가 있는 UTF-8 파일에 문제가 없습니다.

Excel의 Unicode CSV 파일에 대해 작동하는 것과 작동하지 않는 것에 대해서는 이 질문의 표를 참조하십시오.


참고로 Composer를 사용하는 경우 필요에 따라 추가하는 것이 좋습니다. League\Csv에는 CSV 파일을 작성하기 위한 매우 좋은 API가 있습니다.

「」를 League\Csv이 CSV 파일 작성 방법에 대해서는, 다음의 예를 참조해 주세요.

제 경우, Excel에 UTF-8 문자가 올바르게 표시된 CSV 파일을 작성하려면 다음과 같이 하면 좋습니다.

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

0xEF 0xBB 0xBFBOM Excel을 사용합니다.

실행 방법은 다음과 같습니다(브라우저에서 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 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 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의 제안이 다른 컴퓨터에는 가장 좋은 답이 될 것입니다.그래도 내 문제는 해결되지 않아.

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

CSV 파일에는 바이트 순서 마크가 포함되어 있어야 합니다.

또는 제안 및 회피책으로 HTTP 본문을 사용하여 에코합니다.

추가:

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을 사용하다3번으로 나누다

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

이것으로 csv 파일의 특수문자의 문제가 해결되었습니다.

UTF8은 UTF8을 사용하고 있습니다.이 할 수 있습니다.iconv().

예.

iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),
**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;
}

CSV String을 아이콘v로 변환할 수 있습니다.

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

조사해 보니, UTF-8은 MAC와 Windows에서 동작하고 있지 않기 때문에, Windows-1252로 시험해 보았습니다만, 양쪽에서 서포트되고 있습니다만, ubuntu에서 인코딩 타입을 선택할 필요가 있습니다.는 이렇습니다.$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

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

내보내기 전에 파일에 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 파일 생성, 값 내부에 줄바꿈 방법

Mac을 사용하고 있는데, 저 같은 경우 구분 기호를 지정하기만 하면 됩니다."sep=;\n"UTF-16LE 내의 파일을 다음과 같이 부호화합니다.

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

저는 위의 어떤 해결책도 효과가 없었습니다.이 문제를 해결하기 위해 제가 한 일은 다음과 같습니다.PHP 코드의 이 함수를 사용하여 값을 변경합니다.

$value = utf8_encode($value);

이 출력은 Excel 시트로 올바르게 평가됩니다.

데이터를 Import하는 Excel VBA 루틴을 했을 때도 같은 문제가 있었습니다.CSV는 일반 텍스트 형식이기 때문에 워드패드 등의 간단한 파일 에디터로 데이터를 프로그램적으로 열고 유니코드 텍스트로 다시 저장하거나 거기에서 클립보드에 복사하여 엑셀에 붙여넣는 등 작업을 하고 있었습니다.Excel이 CSV를 자동으로 셀로 해석하지 않으면 내장된 "텍스트 투 컬럼" 기능을 사용하여 쉽게 수정할 수 있습니다.

파일을 .txt 파일로 저장해도 쉼표로 구분하여 Excel로 열어도 문제가 발생합니까?

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

이 헤더를 사용하여 Windows 7 PC에서 Excel 2013을 사용하여 특수 문자의 CSV 파일을 올바르게 Import했습니다.BOM(Byte Order Mark)이 동작하는 최종 키입니다.


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

Mac Excel 2008용 EASY 솔루션: 여러 번 고심했지만, 여기 간단한 해결책이 있습니다: Textwrangler에서 .csv 파일을 열면 UTF-8 문자가 올바르게 열립니다.이제 아래쪽 상태 표시줄에서 파일 형식을 "Unicode(UTF-8)"에서 "Western(ISO Latin 1)"로 변경하고 파일을 저장합니다.Mac Excel 2008으로 이동하여 [File]> [ Import ]> [ Select csv ]> [ Find your file ]를 선택하고 [File origin]에서 [Windows (ANSI)]를 선택하면 UTF-8 문자가 올바르게 표시됩니다.적어도 나한테는...

이걸 쓰면 효과가 있어요.

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;

나한텐 일인데.

$df = fopen("File.csv", "w");
header('Content-Encoding: UTF-8');
header("Content-type: text/csv charset=UTF-8");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Location: Path/File.csv');
header('Content-Transfer-Encoding: binary');
header("Pragma: no-cache");
header("Expires: 0");
fputs($df, $bom = ( chr(0xEF) . chr(0xBB) . chr(0xBF) ));

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

반응형