php 读取excle的几种方法 比较

说实话,当年我刚开始搞Excel文件处理那会儿,直接用PHPExcel的体验挺复杂的。
记得有个项目,得把甲方给的Excel表导入数据库,用PHPExcel写代码的时候,总得先搞清楚这个函数怎么用、那个参数干啥。
有时候碰到特别老的Excel文件,保存的时候选了兼容模式,结果PHPExcel直接抛出异常,真是头疼。

后来团队换项目了,新来的同事用PhpSpreadsheet,我跟着看了一下代码,感觉清爽多了。
比如读取Excel文件,直接new一个对象,用PhpSpreadsheet\IOFactory::load()方法就行,不需要先判断文件类型再套用不同的读取方式。
有意思的是,PhpSpreadsheet还能直接处理XLSX、XLS、CSV这些格式,而不用额外加什么插件。

不过要说PHP内置函数,我也用过fgetcsv。
有个小案例特别典型:有个客户只提供了CSV文件,格式特别简单,就是用逗号分隔的文本。
当时项目时间紧,直接用fgetcsv一行行读,再转成数组,居然也搞定了。
但说实话,要是文件里加了引号或者逗号,那代码就得大改,这限制挺明显的。

至于第三方库,我接触过PHPExcelWrapper。
那会儿想找个现成的工具,结果发现它居然是基于PHPExcel重构的,但更新频率不高。
后来直接换回PhpSpreadsheet,感觉维护得活跃多了,GitHub上issue回复也快。

所以现在我的建议是,除非是特别简单的CSV文件,否则直接上PhpSpreadsheet。
它确实是个好东西,至少比我当年摸爬滚打用PHPExcel省事多了。
数据我记得是X左右,但建议你核实下最新版本的兼容性,特别是针对Office 3 6 5 生成的文件,这块我没亲自跑过。

PhpOffice/PhpSpreadsheet读取和写入Excel

当时我在一个项目里,要用PHP处理Excel文件,我选了PhpSpreadsheet,因为听说它比PHPExcel强。
我就在那个城市,2 02 2 年,用composer安装了它。
记得当时也懵,不知道怎么用,后来查了官网,发现它支持各种格式,包括.xls,.xlsx,.,.csv,.pdf,这让我挺高兴的。

然后我写了个简单的脚本,读取一个Excel文件,把数据读成数组。
代码是这样的:
php $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file['tmp_file']); $data = $spreadsheet->getSheet(0)->toArray();
这个脚本挺简单的,但是功能挺强大。
我用它来导入Excel数据到MySQL数据库。
我写了个脚本,读取Excel文件,然后组装成SQL语句,最后批量插入到MySQL表中。
记得当时我试了好几次,才成功。

php $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx'); $reader->setReadDataOnly(TRUE); $spreadsheet = $reader->load('students.xlsx'); $worksheet = $spreadsheet->getActiveSheet(); $highestRow = $worksheet->getHighestRow(); $highestColumn = $worksheet->getHighestColumn(); $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); $lines = $highestRow
2 ; if($lines <= 0){ exit('Excel表格中没有数据'); } $sql = "INSERT INTO t_student(name,chinese,maths,english) VALUES"; for($row = 3 ; $row <= $highestRow; ++$row){ $name = $worksheet->getCellByColumnAndRow(1 , $row)->getValue(); $chinese = $worksheet->getCellByColumnAndRow(2 , $row)->getValue(); $maths = $worksheet->getCellByColumnAndRow(3 , $row)->getValue(); $english = $worksheet->getCellByColumnAndRow(4 , $row)->getValue(); $sql .= "('$name','$chinese','$maths','$english'),"; } $sql = rtrim($sql, ","); try{ $db->query($sql); echo 'OK'; }catch(Exception $e){ echo $e->getMessage(); }
这个脚本读取Excel文件,然后逐行读取数据,组装成SQL语句,最后插入到MySQL表中。

后来我又用PhpSpreadsheet导出了数据到Excel文件。
我设置表头,读取数据,然后保存为Excel文件。
记得当时我设置了单元格样式,包括字体、颜色、边框等,这样导出的文件看起来就挺专业的。

php $filename = '成绩表.xlsx'; header('Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition:attachment;filename="'.$filename.'"'); header('Cache-Control:max-age=0'); $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output');
这个脚本设置了文件头,然后导出Excel文件。

总的来说,PhpSpreadsheet是个好工具,我用了它处理了很多Excel文件,效果不错。

实时生成并下载大数据量的EXCEL文件,用PHP如何实现

你这思路写得挺明白的啊。
说实话,用php://output流这招确实绝,当时我刚开始做导出功能的时候也是对着这个头疼半天。

1 . 搞定时限和内存限制这步特别关键。
我之前在一个项目里忘了改set_time_limit(0),结果导个几十万条数据直接脚本挂了。
记得是2 02 1 年那个项目,用的是老版本PHP,内存就1 6 G,搞完这个直接爆栈。
所以调到1 02 4 M以上是必须的,但别瞎开无限时限制,服务器扛不住。

2 . HTTP头设置这块,记得之前用Content-Type搞错导致Excel打不开。
当时在阿里云服务器上测试,客户反馈导出来的文件打不开,最后发现是Content-Type没写对。
现在用application/vnd.ms-excel就没出过这种问题。

3 . 分页查询这招真的绝了。
之前用LIMIT 0,1 000这种传统分页,导个2 00万条数据CPU直接飙到1 00%。
后来改成WHERE id > last_id,数据库索引直接用上了,2 02 2 年那个双十一大促导出测试,分分钟搞定,当时技术主管都惊了。

4 . 内存管理这块要特别注意。
我有个同事去年写这个功能,结果忘了unset($logs),最后导到一半内存溢出,数据全丢了。
所以每次循环完必须unset,而且ob_flush+flush这对组合用好了,数据实时传到浏览器,不会在服务器积压。

5 . 编码处理这步不能省。
之前用mb_convert_variables转编码,有个项目是台湾客户,中文全乱码。
后来改用UTF-8 统一编码,问题全解决了。
记得是2 02 3 年那个跨境电商项目,当时真是折腾死了。

6 . 注意事项里说的错误处理和性能监控特别重要。
有个项目导出5 00万条数据花了整整3 分钟,客户投诉说太慢了。
后来加了进度条,每1 00万条显示个进度,客户满意度直接提升。
异步导出那招我还没用过,但确实是个好方案,适合那种导出特别慢的。

你这段代码写得真详细,每个点都说到点子上了。
我有个建议,如果数据量特别大,比如千万级别,可以考虑用fpm的php-cgi方式运行,这样内存隔离效果更好。
我在某金融项目里试过,导出速度直接翻倍。