Câu hỏi Làm thế nào tôi có thể xuất UTF-8 CSV bằng PHP mà Excel sẽ đọc đúng?


Tôi đã có điều này rất đơn giản mà chỉ cần đầu ra một số công cụ ở định dạng CSV, nhưng nó đã được UTF-8. Tôi mở tập tin này trong TextEdit hoặc TextMate hoặc Dreamweaver và nó hiển thị các ký tự UTF-8 đúng cách, nhưng nếu tôi mở nó trong Excel, nó sẽ làm điều này một cách ngớ ngẩn. Dưới đây là những gì tôi đã có ở phần đầu của tài liệu của tôi:

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

Tất cả điều này dường như có hiệu quả mong muốn ngoại trừ Excel (Mac, 2008) không muốn nhập nó đúng cách. Không có lựa chọn nào trong Excel cho tôi để "mở như UTF-8" hay bất cứ thứ gì, vì vậy ... Tôi thấy hơi khó chịu.

Tôi dường như không thể tìm thấy bất kỳ giải pháp rõ ràng cho bất cứ nơi nào, mặc dù rất nhiều người có cùng một vấn đề. Điều tôi thấy nhiều nhất là bao gồm BOM, nhưng tôi không thể tìm ra cách để làm điều đó. Như bạn có thể thấy ở trên tôi chỉ echoing dữ liệu này, tôi không viết bất kỳ tập tin nào. Tôi có thể làm điều đó nếu tôi cần, tôi không chỉ vì không có vẻ như cần thiết cho nó vào thời điểm này. Bất kỳ giúp đỡ?

Cập nhật: Tôi đã cố gắng lặp lại BOM như echo pack("CCC", 0xef, 0xbb, 0xbf); mà tôi vừa lấy từ một trang web đang cố gắng phát hiện BOM. Nhưng Excel chỉ chắp thêm ba ký tự đó vào ô đầu tiên khi nó nhập, và vẫn làm rối loạn các ký tự đặc biệt.


156
2017-12-03 18:49


gốc


Excel không cung cấp tùy chọn để điều chỉnh bộ ký tự của tệp đến? Bạn có chắc chắn 100% về điều đó không? Tôi không có một bản sao tiện dụng vì vậy tôi không thể thử nhưng tôi tưởng tượng ở đó phải là một hộp thả xuống ở đâu đó. - Pekka 웃
Đây là Excel trên máy Mac - có vẻ như bị hạn chế hơn Excel trên PC. Không có trình đơn thả xuống nào cả trong hộp thoại Mở, ngoài các loại tệp để có thể mở. Tôi đã nhìn khắp mọi nơi. Nếu nó ở đó, nó tối nghĩa. Tôi nói chắc chắn 98%. - Ben Saufley
Microsoft văn phòng hoặc openoffice? - ajreal
Microsoft, thật không may. - Ben Saufley
Microsoft là tốt hơn trong lĩnh vực này, không có cách nào (mà tôi đã tìm thấy) để làm cho OpenOffice phát hiện bộ ký tự, thậm chí không phải là BOM. Khỉ thật. - Ciantic


Các câu trả lời:


Để trích một kỹ sư hỗ trợ của Microsoft,

Excel cho Mac hiện không hỗ trợ UTF-8

Cập nhật, 2017: Điều này đúng với tất cả các phiên bản Microsoft Excel dành cho Mac trước đây Office 2016. Phiên bản mới hơn (từ Office 365) hiện hỗ trợ UTF-8.

Để xuất nội dung UTF-8 mà Excel cả trên Windows và OS X sẽ có thể đọc thành công, bạn sẽ cần thực hiện hai việc:

  1. Đảm bảo rằng bạn chuyển đổi văn bản UTF-8 sang UTF-16LE

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
  2. Đảm bảo rằng bạn thêm dấu thứ tự byte UTF-16LE

    chr(255) . chr(254)
    

Vấn đề tiếp theo chỉ xuất hiện với Excel trên OS X (nhưng không phải Windows) sẽ hiển thị khi xem tệp CSV có giá trị được phân cách bằng dấu phẩy, Excel sẽ chỉ hiển thị các hàng bằng một hàng và tất cả văn bản cùng với dấu phẩy ở hàng đầu tiên.

Cách để tránh điều này là sử dụng các tab làm giá trị được tách riêng của bạn.

Tôi đã sử dụng chức năng này từ các bình luận PHP (sử dụng các tab "\ t" thay vì dấu phẩy) và nó hoạt động hoàn hảo trên OS X và Windows Excel.

Lưu ý rằng để khắc phục sự cố với cột trống ở cuối hàng, tôi đã phải thay đổi dòng mã cho biết:

    $field_cnt = count($fields);

đến

    $field_cnt = count($fields)-1;

Như một số nhận xét khác trên trang này cho biết, các ứng dụng bảng tính khác như OpenOffice Calc, Số riêng của Apple và Bảng tính của Google Tài liệu không có vấn đề với tệp UTF-8 bằng dấu phẩy.

Xem bảng trong câu hỏi này cho những gì hoạt động và không hoạt động đối với các tệp CSV Unicode trong Excel


Là một lưu ý phụ, tôi có thể thêm rằng nếu bạn đang sử dụng Nhà soạn nhạc, bạn nên xem xét thêm League\Csv theo yêu cầu của bạn. League\Csv có một API thực sự tốt đẹp để tạo tệp CSV.

Để sử dụng League\Csv với phương pháp tạo tệp CSV này, hãy xem ví dụ này


105
2018-05-27 04:14



Giải pháp duy nhất giải quyết vấn đề của tôi, cảm ơn! - Luis Dalmolin
Giải pháp duy nhất làm việc cho tôi, cảm ơn! - di3sel
Giải pháp này cũng giải quyết vấn đề UTF8 cho tôi trên Mac và Windows. Tôi cũng thấy rằng thêm một dòng với sep=; hoặc là sep=, vào tệp CSV cho Excel biết cách CSV được phân tách và các cột sẽ được tạo lại chính xác. - Luc Wollants
Tôi thấy rằng mọi thứ xuất hiện bị cắt xén nếu tôi bắt đầu chuỗi chỉ là BOM, sau đó trên một dòng khác đã thêm "sep=,\n", sau đó trên một dòng khác đã thêm dữ liệu. Mọi thứ đều ổn nếu tôi làm tất cả trong một dòng ($csv = chr(255) . chr(254) /* BOM */ . "sep=,\n" . mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');). Mọi thứ trông tuyệt vời trên Mac. Tôi không có Windows để kiểm tra. - tremby
Chỉ có điều hoàn toàn làm việc cho tôi. Sự mâu thuẫn của Microsoft không bao giờ hết làm tôi ngạc nhiên. Lưu tệp csv bình thường sử dụng dấu "," làm dấu phân tách nhưng nếu có BOM lưu, hãy sử dụng "\ t" vì lý do nào đó. Chữ C trong .csv là viết tắt của "COMMA" dammit. Nó thực sự không khó để làm. - Phil


Tôi có cùng một vấn đề (hoặc tương tự).

Trong trường hợp của tôi, nếu tôi thêm một BOM vào đầu ra, nó hoạt động:

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

Tôi tin rằng đây là một hack khá xấu xí, nhưng nó làm việc cho tôi, ít nhất là cho Excel 2007 Windows. Bạn không chắc chắn nó sẽ hoạt động trên Mac.


250
2017-12-14 14:24



Xấu xí, nhưng siêu hữu ích. Cảm ơn bạn. - abelito
Tôi khá chắc chắn điều này không làm việc tốt trên tất cả trên OS X, không may. Tôi nghĩ rằng nó thực sự có thể hiển thị các BOM khi bạn nhập khẩu (cảnh báo: những kỷ niệm mờ.) - davidtbernal
Chính xác. Ít nhất, tôi đã thử chuẩn bị trước với một BOM, như trong ví dụ trên, nhưng nó thực sự chỉ cho thấy một số ký tự sôi nổi lúc đầu và tiếp tục hiển thị các ký tự đặc biệt sai (thử nghiệm trong Excel 2011). Điều này có vẻ phù hợp nhất với tôi trong mọi cài đặt: stackoverflow.com/a/1648671/1005334 (sử dụng PHP). - kasimir
Cảm ơn bạn, điều này hoạt động như một say mê! - Luigi
Tôi tiếp tục nhận được cảnh báo về câu hỏi này bởi vì dường như rất nhiều người khác tình cờ gặp nó. Tôi ước tôi có thể đánh dấu điều này là chính xác, bởi vì nó đã được upvoted rất nhiều. Thật không may, cuối cùng tôi đã đưa ra giải pháp này một shot (bị bỏ rơi dự án đó từ lâu) và nó không làm việc cho tôi trong Excel 2008 cho Mac. Vui mừng nó làm việc cho bạn. Tôi đã upvoted giải pháp. Nhưng nó không giải quyết vấn đề Excel cho Mac 2008. Nếu ai đó có may mắn trên máy Mac, chắc chắn hãy để tôi (và rõ ràng tất cả mọi người) biết. - Ben Saufley


Đây là cách tôi đã làm nó (đó là để nhắc nhở trình duyệt để tải về các tập tin 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();

Điều duy nhất nó cố định vấn đề mã hóa UTF8 trong xem trước CSV khi bạn nhấn thanh không gian trên máy Mac .. nhưng không phải trong Excel Mac 2008 ... không biết tại sao


28
2017-09-29 17:36



UTF-8 BOM dòng mã tiết kiệm ngày của tôi với xuất khẩu sang xls - Mladen Janjetovic
Tôi đã tìm kiếm một cách để sản xuất trực tiếp đến trình duyệt như utf8, khi tôi đi qua bài đăng này, Đây là giải pháp của tôi với các khoản tín dụng cho bài đăng này cho BOM và tiêu đề chuyển giao nhị phân. $outstream = fopen( "php://output", 'w' ); fputs( $outstream, "\xEF\xBB\xBF" ); foreach ( $export as $fields ) { fputcsv( $outstream, $fields ); } fclose( $outstream ); - fyrye
Typo - loại bỏ các đôi )). - sitilge


Tôi chỉ xử lý cùng một vấn đề và đưa ra hai giải pháp.

  1. Sử dụng PHPExcel lớp học  theo đề xuất của bpeterson76.

    • Sử dụng lớp này tạo ra tệp tương thích rộng rãi nhất, tôi có thể tạo tệp từ dữ liệu được mã hóa UTF-8 đã mở tốt trong Excel 2008 Mac, Excel 2007 Windows và Google Tài liệu.
    • Vấn đề lớn nhất khi sử dụng PHPExcel là nó chậm và sử dụng nhiều bộ nhớ, đây không phải là vấn đề cho các tệp có kích thước hợp lý, nhưng nếu tệp Excel / CSV của bạn có hàng trăm hoặc hàng nghìn, thư viện này sẽ trở thành không sử dụng được.
    • Đây là một phương thức PHP sẽ lấy một số dữ liệu TSV và xuất ra một tệp Excel cho trình duyệt, lưu ý rằng nó sử dụng Writer Excel5, có nghĩa là tệp phải tương thích với các phiên bản Excel cũ hơn, nhưng tôi không còn quyền truy cập vào bất kỳ, vì vậy tôi không thể kiểm tra chúng.

      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. Vì vấn đề hiệu quả với PHPExcel, tôi cũng phải tìm ra cách tạo tệp CSV hoặc TSV tương thích UTF-8 và Excel.

    • Điều tốt nhất tôi có thể đưa ra là một tệp tương thích với Excel 2008 Mac và Excel 2007 PC, nhưng không phải là Google Documents, đủ tốt cho ứng dụng của tôi.
    • Tôi tìm thấy giải pháp đây, đặc biệt, câu trả lời này, nhưng bạn cũng nên đọc câu trả lời được chấp nhận vì nó giải thích vấn đề.
    • Đây là mã PHP tôi đã sử dụng, lưu ý rằng tôi đang sử dụng dữ liệu tsv (các tab làm dấu phân cách thay vì dấu phẩy):

      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;
      

21
2018-01-21 19:00



tôi đang đối mặt với cùng một vấn đề trên Windows-7 Excel 2007 và đã thử tất cả các đề xuất nhưng không thành công :( - PHP Ferrari
Giải pháp UTF-16LE là giải pháp hiệu quả. Lưu ý rằng bạn phải định dạng chính xác tsv và nó phải là tsc, do đó, được phân tách bằng tab, không được phân tách bằng dấu phẩy. Xem thêm bài viết của Marc tại đây: stackoverflow.com/a/1648671/1697370 - Ellert van Koperen
Jasdeep, cảm ơn một tấn cho gợi ý! - AntonSack


Excel không hỗ trợ UTF-8. Bạn phải mã hóa văn bản UTF-8 của bạn thành UCS-2LE.

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

12
2017-11-08 13:47



Sử dụng UTF-16LE tốt hơn như đề xuất ở trên, bao gồm mọi ký tự tồn tại. - Ellert van Koperen
Tôi đã nhận thấy mb_convert_encoding này hoạt động tốt và hiển thị dấu phụ chính xác trong tệp XLS được xuất của tôi. Tôi có cấu hình mặc định mysql và apache + php được thiết lập để làm việc với utf-8 - Junior M


Tôi đã gặp vấn đề tương tự và nó đã được giải quyết như sau:

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

11
2017-12-18 16:31





Để theo dõi điều này:

Có vẻ như vấn đề chỉ đơn giản là với Excel trên máy Mac. Nó không phải là cách tôi tạo ra các tập tin, bởi vì thậm chí tạo ra CSV từ Excel đang phá vỡ chúng. Tôi lưu dưới dạng CSV, và nhập lại, và tất cả các nhân vật đều bị rối tung lên.

Vì vậy ... có vẻ như không có câu trả lời đúng cho điều này. Cảm ơn tất cả những lời đề nghị.

Tôi sẽ nói rằng từ tất cả những gì tôi đã đọc, gợi ý của @Daniel Magliola về BOM có lẽ sẽ là câu trả lời tốt nhất cho một số máy tính khác. Nhưng nó vẫn không giải quyết được vấn đề của tôi.


8
2018-01-11 16:56



Vì hỗ trợ UTF8 không nhất quán trên Mac so với Windows, nên đặt cược tốt nhất là sử dụng mã hóa hoàn toàn khác. Tôi đã tìm thấy cp1252 thường chơi tốt với công cụ của Microsoft. en.wikipedia.org/wiki/Windows-1252 - s29
Ben, có một câu trả lời đúng cho câu hỏi này :) Xem của tôi! - Tim Groeneveld


Tệp CSV tập tin bao gồm Dấu đơn hàng Byte.

Hoặc như được đề xuất và giải pháp thay thế, chỉ cần lặp lại với cơ thể HTTP


6
2017-10-20 08:56