Export CSV for Excel

前端 未结 5 1245
耶瑟儿~
耶瑟儿~ 2020-12-29 16:58

I\'m writing a CSV file in PHP using fputcsv($file, $data). It all works, however I can\'t just open it in Excel but have to import it and specify the encoding

5条回答
  •  不思量自难忘°
    2020-12-29 17:40

    I notice that you need to consider: Content-Type header BOM (Byte Order Mark) Actual character encoding in the file

    With BOM (works):

    $bom = pack("CCC", 0xEF, 0xBB, 0xBF);
    header('Content-Type: text/csv');
    header('Content-Length: '.(strlen($csv)+strlen($bom)));
    header('Content-Disposition: attachment;filename=my.csv');
    echo $bom;
    echo $csv;
    

    Without BOM (works but you need to replace “smart quotes” then run utf8_decode on each value or cell, and it converts some characters, for example FRĒ is converted to FRE')

    header('Content-Type: application/csv;charset=utf-8');
    header('Content-Length: '.strlen($csv));
    header('Content-Disposition: attachment;filename=my.csv');
    echo $csv;
    

    If the wrong combination of charset and BOM are used, it just comes out wrong when opening in MS Excel.

    Bonus fact: mb_strlen tells you the number of characters, strlen tells you the number of bytes. You do NOT want to use mb_strlen for calculating the Content-Length header.

    Bonus 2: replace microsoft "smart" characters (em dash, curly quotes, etc):

    $map = array(chr(145) => "'"
                ,chr(146) => "'"
                ,chr(147) => '"'
                ,chr(148) => '"'
                ,chr(149) => '-'
                ,chr(150) => '-'
                ,chr(151) => '-'
                ,chr(152) => '-'
                ,chr(152) => '-'
                ,chr(171) => '-'
                ,chr(187) => '-'
    );
    // faster that strtr
    return str_replace( array_keys($map), $map, $str );
    

提交回复
热议问题