Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中输出UTF-8 CSV,以便Excel正确读取?_Php_Csv_Utf 8_Byte Order Mark - Fatal编程技术网

如何在PHP中输出UTF-8 CSV,以便Excel正确读取?

如何在PHP中输出UTF-8 CSV,以便Excel正确读取?,php,csv,utf-8,byte-order-mark,Php,Csv,Utf 8,Byte Order Mark,我有一个非常简单的东西,只输出一些CSV格式的东西,但它必须是UTF-8。我在TextEdit、TextMate或Dreamweaver中打开这个文件,它会正确显示UTF-8字符,但如果我在Excel中打开它,它会做这种愚蠢的事情。以下是我在文件开头的内容: header("content-type:application/csv;charset=UTF-8"); header("Content-Disposition:attachment;filename=\"CHS.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
ing这个数据,我没有写任何文件。如果我需要的话,我可以这样做,我只是没有,因为在这一点上似乎没有必要。有什么帮助吗


更新:我尝试将BOM作为
echo包(“CCC”,0xef,0xbb,0xbf)进行回显我刚从一个试图检测BOM的站点中提取。但是Excel在导入时只是将这三个字符附加到第一个单元格中,并且仍然会弄乱特殊字符。

我在使用Excel VBA例程导入数据时也遇到了同样的问题。由于CSV是纯文本格式,我通过编程在一个简单的文件编辑器(如写字板)中打开数据,然后将其重新保存为unicode文本,或者将其复制到剪贴板并粘贴到Excel来解决这个问题。如果excel无法自动将CSV解析为单元格,则可以使用内置的“文本到列”功能轻松解决此问题。

当您将其保存为.txt文件并在excel中以逗号作为分隔符打开该文件时,是否仍会出现此问题


问题可能根本不是编码,可能只是根据excel标准,该文件不是一个完美的CSV。

只输出excel本身如何?这允许您在服务器端生成XLS文件。我经常为那些无法“理解”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
我相信这是一个相当丑陋的黑客行为,但它对我有效,至少对Excel2007Windows有效。不确定它是否能在Mac上工作。

要继续此操作:

问题似乎只是在于Mac上的Excel。这不是我生成文件的方式,因为即使从Excel生成CSV也会破坏它们。我保存为CSV,然后重新导入,所有字符都被弄乱了

所以…似乎没有一个正确的答案。谢谢你的建议


据我所知,@Daniel Magliola关于BOM的建议可能是其他计算机的最佳答案。但它仍然不能解决我的问题。

我只是处理了同样的问题,并提出了两个解决方案

  • 使用该类

    • 使用这个类生成最广泛兼容的文件,我能够从UTF-8编码的数据生成一个文件,这些数据在Excel2008Mac、Excel2007Windows和Google文档中打开良好
    • 使用PHPExcel的最大问题是速度慢且占用大量内存,这对于大小合理的文件来说不是问题,但是如果Excel/CSV文件有数百行或数千行,此库将无法使用
    • 这里是一个PHP方法,它将获取一些TSV数据并将Excel文件输出到浏览器,请注意,它使用的是Excel 5 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;   
      }
      
  • 由于PHPExcel的效率问题,我还必须找出如何生成与UTF-8和Excel兼容的CSV或TSV文件

    • 我能想到的最好的是一个与Excel2008Mac和Excel2007PC兼容的文件,而不是谷歌文档,这对我的应用程序来说已经足够好了
    • 我找到了具体的解决方案,但您也应该阅读,因为它解释了问题
    • 以下是我使用的PHP代码,请注意,我使用的是tsv数据(制表符作为分隔符,而不是逗号):

  • 我是这样做的(即提示浏览器下载csv文件):


    当你在Mac上点击空格键时,它唯一修复了CSV预览中UTF8编码问题。。但不是在Excel Mac 2008中。。。不知道为什么CSV文件不包含字节顺序标记


    或者,根据建议和解决方法,只需使用HTTP正文将其回显即可。您可以使用iconv将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) );
    

    Excel不支持UTF-8。您必须将UTF-8文本编码为UCS-2LE

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

    因为UTF8编码不能很好地与Excel配合使用。您可以使用
    iconv()
    将数据转换为另一种编码类型

    e、 g


    您必须使用编码“Windows-1252”

    header('Content-Encoding:Windows-1252');
    标题('Content-type:text/csv;charset=Windows-1252');
    标题(“内容处置:附件;文件名={$filename}”);
    
    也许您必须转换字符串:

    私有函数convertToWindowsCharset($string){
    $encoding=mb_detect_encoding($string);
    返回iconv($encoding,“Windows-1252”,$string);
    }
    
    这篇文章已经很老了,但经过几个小时的尝试,我想分享我的解决方案……也许它能帮助处理Excel、Mac和CSV的人,并在这个威胁面前绊倒。我将动态生成一个csv作为数据库的输出,并考虑Excel用户。(带BOM的UTF-8)

    我尝试了很多iconv,但无法让德国UMLAUT在MacExcel2004中工作。一个解决方案:PHPExcel。它是
    $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) );
    
    mb_convert_encoding($output, 'UCS-2LE', 'UTF-8');
    
    iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),
    
    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
    chr(255) . chr(254)
    
        $field_cnt = count($fields);
    
        $field_cnt = count($fields)-1;
    
    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
    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 );
    
    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);
    
    $newContent = chr(239) . chr(187) . chr(191) . $originalContent
    
    //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"));
    
        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();
    
    fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
    
    fprintf($file, "\xEF\xBB\xBF");
    
    <?php
    $file = fopen( "file.csv", "w");
    fprintf( $file, "\xEF\xBB\xBF");
    fputcsv( $file, ["english", 122, "বাংলা"]);
    fclose($file);
    
    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;
    
    $data = "sep=;\n" .mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');
    
    $value = utf8_encode($value);
    
    //Use tab as field separator   
    $sep  = "\t";  
    $eol  = "\n";    
    $fputcsv  =  count($headings) ? '"'. implode('"'.$sep.'"', $headings).'"'.$eol : '';
    
    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;
    }
    
    $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
    
    $out = fopen('php://output', 'w');
    fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
    fputcsv($out, $some_csv_strings);
    
    **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;
    }