如何导出中文报表

前提:

使用 utf-8 编码。

支持 macOS 上的 Numbers 和 Windows 上的 Excel 打开。(LibreOffice Calc 没有测试,Linux爱好者可以帮忙测试。)


1. 导出 Excel

这里我们使用 PHPOffice(https://github.com/PHPOffice)。PHPOffice 有两个导出 Excel 的项目,PHPExcel 和 PhpSpreadsheet,PHPExcel 支持 PHP 5.2 及以上的版本,PhpSpreadsheet 支持 PHP5.6 及以上的版本,具体的区别可以查看 Github 页面上的对比。


PHPExcel vs PhpSpreadsheet ?

PhpSpreadsheet is the next version of PHPExcel. It breaks compatibility to dramatically improve the code base quality (namespaces, PSR compliance, use of latest PHP language features, etc.).

Because all efforts have shifted to PhpSpreadsheet, PHPExcel will no longer be maintained. All contributions for PHPExcel, patches and new features, should target PhpSpreadsheet develop branch.

However PhpSpreadsheet is still unstable and not yet released. So if you need stability stick to PHPExcel until this project is released. If you prefer to live on the edge you can try to install this project manually via composer, but there is no guarantee and it will likely break again before an official release.

简单来说,PhpSpreadsheet 是用来代替 PHPExcel 的。不过由于 PhpSpreadsheet 现在还没有发布稳定版,所以我们这里还是使用 PHPExcel。

推荐使用 composer 安装。

composer require phpoffice/phpexcel

Examples 目录下有详细的示例代码,可以参考。


// Create new PHPExcel object
$objPHPExcel = new PHPExcel();

// Set document properties
$objPHPExcel->getProperties()->setCreator("Victor Tang")
    ->setLastModifiedBy("Victor Tang")
    ->setTitle("PHPExcel Test Document")
    ->setSubject("PHPExcel Test Document");

// Add some data
$objPHPExcel->setActiveSheetIndex(0)
    ->setCellValue('A1', 'Hello')
    ->setCellValue('B2', 'world!')
    ->setCellValue('C1', '你好')
    ->setCellValue('D2', '世界!');

// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="PHPExcel Test Document.xlsx"');
header('Cache-Control: max-age=0');

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');

2. 导出 CSV

直接导出 UTF-8 格式的 CSV 文件在 macOS 和 Linux 系统是能完美支持的,但是在 Windows 下打开可能就会乱码,所以这里我们需要导出 UTF-8 with BOM 格式的 CSV 文件。


// UTF-8 with BOM
$csv = chr(0xEF) . chr(0xBB) . chr(0xBF);

$csv .= "Hello,World\n";
$csv .= "你好,世界\n";

测试了 macOS 上的 Numbers 和 Excel 2016,Excel 格式和 UTF-8 with BOM 的 CSV 格式都没有乱码。一台 Windows 10 + Excel 2007 的机器上 UTF-8 with BOM 的 CSV 格式乱码了,一台 Windows 7 + Excel 2007 的机器上 UTF-8 with BOM 的 CSV 格式没有乱码。

样本太少,也不好下什么结论,虽然有一台机子打开乱码了,但是我还是认为 Excel 格式和 UTF-8 with BOM 的 CSV 格式应该是可以兼容所有操作系统的。另外在搜索资料的过程中看到好多叫嚣 “UTF-8 without BOM 才是正统” 的文章,还是不禁有些感概。比起讨论开源还是闭源,理论标准还是事实标准,我们更需要的是能够解决实际问题的方法。


参考:

https://github.com/PHPOffice/PhpSpreadsheet

https://github.com/PHPOffice/PHPExcel

https://stackoverflow.com/questions/5601904/encoding-a-string-as-utf-8-with-bom-in-php

https://en.wikipedia.org/wiki/Byte_order_mark

 731 total views,  1 views today

Leave a Reply

Your email address will not be published. Required fields are marked *