尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
十万条数据导出实战:避免内存爆掉的终极技巧
上周帮同事处理一个后台导出需求数据量大概十万条出头一开始用最土的办法拼 CSV结果运营那边打开就乱码还丢了几列。后来换成 PhpSpreadsheet折腾了一下午总算跑通顺手把踩过的坑记下来给同样要做导出的朋友省点时间。一、先装依赖别急着写代码PhpSpreadsheet 是 PHPExcel 的官方继任者PHPExcel 早就停止维护了新项目别再用了。用 Composer 装一下就行composer require phpoffice/phpspreadsheet注意版本和 PHP 版本要对得上。PhpSpreadsheet 2.x 要求 PHP 8.1 以上如果你的项目还跑在 PHP 7.4那就锁 1.x 的版本不然装完直接报语法错误。另外记得确认ext-gd、ext-zip、ext-xml这几个扩展是开着的导出 xlsx 会用到 zip。二、最基础的导出写法先看一个能跑的最小例子把数组写进单元格再输出?php require vendor/autoload.php; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; $spreadsheet new Spreadsheet(); $sheet $spreadsheet-getActiveSheet(); // 表头 $sheet-fromArray([ID, 用户名, 邮箱, 注册时间], null, A1); // 数据 $rows [ [1, 张三, zhangsanexample.com, 2024-01-01], [2, 李四, lisiexample.com, 2024-01-02], ]; $sheet-fromArray($rows, null, A2); $writer new Xlsx($spreadsheet); $writer-save(demo.xlsx);这段代码跑起来没问题但如果你直接把它套到十万条数据上大概率会遇到两个情况一是内存爆掉二是浏览器一直转圈最后超时。三、十万条数据的关键分批写入 关掉缓存PhpSpreadsheet 默认会把每个单元格对象都放在内存里十万行乘以十几列内存占用轻松上 G。解决办法其实不复杂核心就两点用fromArray一次性写一批而不是一个单元格一个单元格地setCellValue写之前把单元格缓存关掉减少对象开销。?php require vendor/autoload.php; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Cell\DataType; // 关掉单元格缓存降低内存 \PhpOffice\PhpSpreadsheet\Settings::setCache(null); $spreadsheet new Spreadsheet(); $sheet $spreadsheet-getActiveSheet(); $sheet-fromArray([ID, 用户名, 邮箱, 注册时间], null, A1); $pdo new PDO(mysql:host127.0.0.1;dbnamedemo;charsetutf8mb4, root, 123456); $pdo-setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pageSize 2000; $page 0; $rowIndex 2; while (true) { $offset $page * $pageSize; $stmt $pdo-prepare(SELECT id, name, email, created_at FROM users LIMIT :offset, :size); $stmt-bindValue(:offset, $offset, PDO::PARAM_INT); $stmt-bindValue(:size, $pageSize, PDO::PARAM_INT); $stmt-execute(); $list $stmt-fetchAll(PDO::FETCH_NUM); if (empty($list)) { break; } $sheet-fromArray($list, null, A . $rowIndex); $rowIndex count($list); $page; // 及时释放 unset($list, $stmt); } $writer new Xlsx($spreadsheet); $writer-save(users.xlsx);这里用分页查询而不是fetchAll一次性捞全表是很关键的一步。十万条数据全塞进 PHP 数组光数组本身就要占不少内存分页之后峰值能压下来一大截。四、几个容易忽略的细节1. 长数字会变成科学计数法。像订单号、身份证号这种Excel 会自动识别成数字然后显示成 1.23E17。写入前把单元格格式设成文本$sheet-setCellValueExplicit(A2, 202401011234567890, DataType::TYPE_STRING);用fromArray批量写的时候可以先把这一列整列设成文本格式再写数据。2. 中文乱码。xlsx 本身是 UTF-8一般不会乱码乱码多半是数据库连接没设charsetutf8mb4或者导出的是 CSV 而不是 xlsx。CSV 的话记得加 BOM。3. 执行时间。十万条数据导出通常要几十秒记得在脚本开头加set_time_limit(0)不然跑到一半被 PHP 掐掉。如果是 Web 请求触发的最好改成异步任务前端轮询下载地址别让用户干等着。4. 内存上限。可以在脚本里临时调一下ini_set(memory_limit, 512M)但更推荐的做法还是控制单次写入的数据量别指望无限加内存。五、数据量再大怎么办如果哪天数据涨到五十万、一百万PhpSpreadsheet 就有点吃力了。这时候可以考虑两个方向一是用Xlsx的流式写入边生成边往临时文件里写二是干脆换 OpenSpout 这类专门为大数据量设计的库内存占用会小很多。不过对大多数后台导出场景来说十万条用 PhpSpreadsheet 完全够用把分批和缓存这两点做好就行。最后提醒一句导出功能上线前一定要拿真实数据量压一遍别等运营点下载的时候才发现超时那就尴尬了。
RELATED

相关推荐

慧知开源GOEMS 综合能源管理系统

慧知开源GOEMS 综合能源管理系统

慧知开源GOEMS 能源管理系统 当前版本:3.0.8 🔥 GOEMS平台微服务源码(当前) 🔥 GOEMS管理后台前端源码 🔥 更新日志 基于 Spring Cloud Alibaba 的多租户能源管理云平台(EMS) 在…

📅 2026/10/24 5:40:58
万圣节快到了:聊得来比装扮更重要,AI 正在悄悄改变节日交流

万圣节快到了:聊得来比装扮更重要,AI 正在悄悄改变节日交流

万圣节快到了:聊得来比装扮更重要,AI 正在悄悄改变节日交流十月底,朋友群里开始讨论万圣节聚会,有人已经挑好了服装,也有人盯着邀请里的“costume encouraged”犹豫:到底要不要认真装扮?穿得太普…

📅 2026/10/24 5:40:58
集装箱损伤检测数据集 | 7731张YOLO港口验箱数据集

集装箱损伤检测数据集 | 7731张YOLO港口验箱数据集

集装箱损伤检测数据集 | 7731张YOLO港口验箱数据集 适用于港口闸口验箱、残损鉴定与目标检测研究 一、数据集概述 本数据集是一个面向港口物流与货运质检场景的集装箱外观损伤检测数据集,共包含7731张高质量标注图像(训练集6331张、验证集933张、测试集…

📅 2026/10/24 5:40:58
MORE NEWS

更多资讯

📰

Seedance 2.5拟真人像提示词四层架构解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

1024 倒计时 24 小时:一个系统级极客的数字生存指南与 Rust 心灵礼物

再过 24 个小时,就是 1024 程序员节。 朋友圈里已经开始被各大互联网大厂的公关通稿刷屏:抽奖、格子衫玩偶、免费下午茶、以及各路大 V 关于“AI 时代程序员会不会被淘汰”的焦虑贩卖。 作为一个在考研泥潭里挣扎过、二本非科班自学转码、靠死磕底层编译…

📰

集体好奇心如何提升技术团队效能与创新

1. 集体好奇心的本质与团队效能集体好奇心不是个体好奇心的简单叠加,而是团队成员在协作过程中形成的知识探索共同体。当团队中存在健康的集体好奇心时,成员会主动分享疑问、共同拆解问题、协作寻找答案,这种动态过程能显著提升团队的知识获取…

📰

技能表达新范式:从静态标签到可验证能力坐标系

1. “skills”不是标签,是能力坐标系的动态刻度最近在几个技术社区和职业发展类平台反复看到一个现象:大量简历、项目介绍、自我介绍里高频出现“skills”这个词,但点开一看,要么是堆砌一长串技术名词,要么是模糊的“熟…

📰

Oracle - 用户权限管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

SystemVerilog线程控制专题:fork/join家族与automatic变量深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬