PHP如何导出CSV文件和TXT文件?如何防止Excel打开CSV乱码?

CSV,是逗号分隔值(Comma Separated Value)的英文缩写,通常都是使用英文逗号(",")分隔的纯文本表格文件。

CSV 格式的文件可以在 Excel 中打开,也可以很快速的转换成 xls/xlsx 格式的文件。

CSV可以使用什么软件打开?

CSV文件是纯文本的数据文件,可以使用任何文本/代码编辑器打开。

为了方便查看,我们常常使用微软Office Excel、 Mac Numbers、金山WPS 等软件打开。

CSV文件的格式?

CSV文件格式:
(1) 以行为单位,每一行记录一条数据。
(2) 每一行的数据中,每一列数据以半角逗号(即英文逗号",")作为分隔符,如果列为空也要有逗号分隔。
(3) 列中的内容如存在半角引号(即"),则替换成半角双引号("")。就是半角单引号需要使用双引号包起来。

使用PHP代码,可以很方便的将数据导出成CSV格式的文件, 下面来看看如何使用PHP来操作CSV吧!

如何将数据导出成CSV格式?

可以直接循环数组数据,使用 fwritefputs 将拼装好的每行的数据写入文件中。

更好的办法是,使用 fputcsv 函数,可以直接将一个数组保存成逗号分隔的一行数据。

直接看代码:

function downloadAsCsvFile( array &$csvTitle, array &$csvData, $fileName='' ) {
    if(empty($fileName)){ //保存的文件名称
      $fileName = 'download_'.date('Ymd_His');
    }
    header('Content-type: application/csv');
    header('Content-Transfer-Encoding: binary; charset=utf-8');
    header('Content-Disposition: attachment; filename='.$fileName.'.csv');
    $fp = fopen("php://output", 'w');
    //生成BOM头
    fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
    //生成标题栏
    fputcsv($fp, $csvTitle);
    foreach ($csvData as $row) {
        fputcsv($fp, $row);
    }
    exit();
}

可以看到代码中有个生成 BOM 头的操作,这是为啥呢?

我们平常编写代码,总是选择将代码文件保存成 “无BOM头的UTF8” 格式。但是因为历史原因,Windows下的文本文件需使用 “有BOM头的UTF8” 格式,否则Excel打开就乱码了。

FROM [itelite博客]:
为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE字符开头。
这作为一个”特征符”或”字节顺序标记(byte-order mark,BOM)”来识别文件中使用的编码和字节顺序(big-endian或little-endian)。
以UTF-8无BOM格式编码,因此要想导出Microsoft Excel可以正常显示的UTF-8的CSV文件,需要显式的输出BOM(EF BB BF),然后再输出有效数据。

如何将数据导出成TXT格式?

同样我们也可以直接下载成TXT格式的文件,使用空格分隔数据。

function downloadAsTxtFile( array &$txtTitle,  array &$txtData, $fileName='' ) {
    if(empty($fileName)){ //保存的文件名称
      $fileName = 'download_'.date('Ymd_His');
    }

    header("Content-Disposition: attachment; filename={$fileName}.txt");
    header("Content-Type: charset=utf-8");
    $fp = fopen("php://output", 'w');

    //生成BOM头
    fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
    //生成标题栏
    $titleLine = implode("\t", $txtTitle)."\n";
    fputs($fp, $titleLine, strlen($titleLine));

    foreach ($txtData as $row) {
        $line = implode("\t", $row)."\n";
        fputs($fp, $line, strlen($line));
    }
    exit();
}

使用示例:

//示例:$data为导出CSV数据
$data = array(
    0 => array('id'=>487, 'date'=>'201605', 'product_id'=>487, 'product_name'=>'法国皇家ROYALCANIN', 'create_time'=>1468931234,),
    1 => array('id'=>13866, 'date'=>'201606', 'product_id'=>13866, 'product_name'=>'BOTH室内挑嘴小型犬奶糕及幼犬500g微生态系列', 'create_time'=>1468810086,),
    2 => array('id'=>20374, 'date'=>'201607', 'product_id'=>20374, 'product_name'=>'Orijen渴望 无谷成犬配方狗粮2.27kg 香港直购', 'create_time'=>1488810010,),
);

$filename = 'TEST_'.date('Ymd').'_'.time();
$download_title = array('ID', '月份', '产品ID', '产品名称','新建时间');
$download_data  = array();//拼装要导出的数据字段
foreach ($data as $key => $row) {
    $download_data[$key]['id']          = $row['id'];
    $download_data[$key]['date']        = $row['date'];
    $download_data[$key]['product_id']  = $row['product_id'];
    $download_data[$key]['product_name']= $row['product_name'];
    $download_data[$key]['create_time'] = ($row['create_time']) ? date('Y-m-d H:i:s', $row['create_time']) : 0; 
}
//导出TXT文件
//downloadAsTxtFile($download_title, $download_data, $filename);

//导出CSV文件
downloadAsCsvFile($download_title, $download_data, $filename);

导出的其他选择

推荐一个比较出名的 CSV 类库:

thephpleague/csv

数据导出除了导出CSV格式文件,也可以直接导出成Excel(xls/xlsx)格式文件,这就需要使用PHPExcel库。

PHPExcel 是用来操作Office Excel 文档的一个PHP类库,它基于微软的OpenXML标准和PHP语言。
可以使用它来读取、写入不同格式的电子表格.

用到的PHP 函数

header() : Send a raw HTTP header
fopen() : Opens file or URL
fclose() : Closes an open file pointer
fputs() : Alias of fwrite()
fwrite() : Binary-safe file write
fputcsv() : Format line as CSV and write to file pointer (PHP 5 >= 5.1.0, PHP 7)

参考链接

http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm#EmbedBRs
http://www.cnblogs.com/itelite/archive/2012/11/28/2792545.html
http://file.org/extension/csv
PHPExcel: https://github.com/PHPOffice/PHPExcel

更新记录

  1. 20160729 新整理本文
  2. 20181207 修订排版,完善内容
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web后端技术

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值