V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
edk24
V2EX  ›  PHP

简单 Excel 导入导出库, 欢迎使用和提意见

  •  
  •   edk24 · 159 天前 · 2379 次点击
    这是一个创建于 159 天前的主题,其中的信息可能已经有所发展或是发生改变。

    composer 包地址: https://packagist.org/packages/yuxiaobo/simple-excel github 源代码: https://github.com/edk24/simple-excel

    开发这个库的初衷是为了快速完成导入导出的功能开发, 一个人做项目的时候 时间就是金钱 哈哈

    你有什么好的想法也欢迎提出, 我会继续打磨完善的.


    🌈 简单使用, 方便快捷。 支持 xls xlsx csv 🌸

    依赖:PhpSpreadsheet

    使用 🎉

    要求 php >= 7.3

    导入

    $arr = SimpleExcel::import(dirname(__DIR__) . '/test/test.xlsx', 'xlsx', array(
        '姓名'      => 'name',
        '年龄'      => 'age',
        '性别'      => 'gender'
    ));
    var_dump($arr);
    

    导出

    // 导出到文件
    SimpleExcel::export('/tmp/dump.xlsx', 'xlsx', [
        'name'      => '姓名',
        'idcard'    => '身份证',
        'mobile'    => '手机号'
    ], [
        ['name' => '张三', 'idcard' => '`522131199703213342', 'mobile'=>'18311548011'],
        ['name' => '李四', 'idcard' => '`522131199703213342', 'mobile' => '18311548011'],
        ['name' => '赵五', 'idcard' => '`522131199703213342', 'mobile' => '18311548011'],
    ],'#ff0000', '#00ff00', '#333333');
    
    // 直接下载导出数据
    SimpleExcel::setDownloadHeader('导出数据.xlsx'); // 设置下载文件响应头
    SimpleExcel::export('php://output', 'xlsx', [
        'name'      => '姓名',
        'idcard'    => '身份证',
        'mobile'    => '手机号'
    ], [
        ['name' => '张三', 'idcard' => '`522131199703213342', 'mobile'=>'18311548011'],
        ['name' => '李四', 'idcard' => '`522131199703213342', 'mobile' => '18311548011'],
        ['name' => '赵五', 'idcard' => '`522131199703213342', 'mobile' => '18311548011'],
    ],'#ff0000', '#00ff00', '#333333');
    

    常见问题 ❓

    1. 导入或导出几十万条数据失败

    ⭐️ 解决办法只有两个 ⭐️

    • ① 分批导入或者导出
    • ② 数据量较大建议做成异步队列,避免影响主业务

    2. 内存超出使用限制

    Allowed memory size of 8388608 bytes exhausted (tried to allocate 1298358 bytes)

    上述问题是由于内存不足导致的,可能是有死循环,或者代码对内存的使用量比较大。

    临时解决办法:ini_set('memory_limit', '256M');

    数据量太大的话,建议导出、导入做成异步任务

    🌸 优化建议 🌸

    • ① 尽量不要使用框架模型,使用大 DB 查数据(以 thinkphp 为例)能明显优化内存与任务耗时
    • ② 只查询需要的字段
    • ③ 使用游标分批查询数据
    • ④ 耗时任务强烈建议做成异步队列的方式!!!不要犟,避免影响主业务

    3. 请求超时

    临时解决:ini_set('max_execution_time', 600);

    也需要注意一下 nginx 的最大保持 http 请求时间

    数据量太大的话,建议导出、导入做成异步任务

    🌸 优化建议 🌸

    • ① 可以临时通过增加 php 执行时间解决 ini_set('max_execution_time', 600);
    • ② 忘记说了,也需要对应增加 nginx/apache 的 http 请求保持时间,它在你的上层~
    • ③ 耗时任务强烈建议做成异步队列的方式!!!不要犟,避免影响主业务

    4. 数字太长变成 E+

    导出时在前面加个单元号或者反单元号,如身份证:522131199703253412 改成 '522131199703253412

    5. 大数据导出

    🌸 建议 🌸

    使用 csv 替代 xlsx ,xls 最大行 65536 ,xlsx 最大行 1048576 (一百万), csv 没有限制

    • ① 如果你是处理大数据,不要用这个库, 直接用 php 的 fputcsvfgetcsv
    • ② 导出几百万上千万的数据,怎么打开?用 UltraEdit 即可,很🐂🍺的

    6. 空行忽略

    遇到空行数据默认是跳过的

    可以通过 simpleExcel::import() 函数的参数 4 ignoreEmptyRow 设置

    第 1 条附言  ·  159 天前
    感谢 @bugsnail @langziyang @QlanQ 推荐的 xlswriter ,这个库使用起来也足够简单。没有二次包装的必要

    我的这个库二三十列几万的数据没啥问题, 并且还用到了背景色边框这些 多少会对性能有些许影响,可以针对一些对数据量没有太大要求的朋友快速完成功能开发 无需安装扩展。大一点的数据我已经优化了 csv 处理。


    我把 `xlswriter` 这个扩展写到 README 大数据处理推荐中去。希望可以帮到更多的人
    17 条回复    2024-05-31 09:45:24 +08:00
    bugsnail
        1
    bugsnail  
       159 天前   ❤️ 4
    大数据建议支持 xlswriter 扩展
    langziyang
        2
    langziyang  
       159 天前
    @bugsnail 正想回复,登录过程慢了一点被你抢先了
    edk24
        3
    edk24  
    OP
       159 天前
    @bugsnail 好的, 我先记录起来 回头看看怎么实现 谢谢 Thanks♪(・ω・)ノ
    QlanQ
        4
    QlanQ  
       159 天前
    xlswriter 不解释
    ShineyWang
        5
    ShineyWang  
       159 天前
    我之前用的[swiftexcel]( https://swiftexcel.pro/)


    100 000 rows and 100 columns 你测试一下你的库性能如何?
    edk24
        6
    edk24  
    OP
       159 天前
    @ShineyWang 还没有做性能测试, 依赖 PhpSpreadsheet 实现的. 目前就我和我朋友在一些小项目中使用;

    看来大家都比较在意大量数据的处理性能和速度, 回头做一个。 谢谢你的建议
    edk24
        7
    edk24  
    OP
       159 天前
    @ShineyWang

    我这个库依赖的 PhpSpreadsheet ,test100000row_and_100column 内存和耗时消耗都巨大,为此我优化了 csv 部分

    足够跑通导出导入,但需要提前组装数据或一次性返回数据。 对内存的占用略高一点( 1.6GB)。 速度还行


    This test printed output: CSV => 100000 行 100 列导出: 耗时:0.980793 sec

    This test printed output: CSV => 100000 行 100 列导入: 耗时:3.367294 sec


    哈哈等我回过头编写 README 准备推荐 `xlswriter` 和 `swiftexcel` 的时候才发现 `swiftexcel` 是 C# 的库。
    Xinu
        8
    Xinu  
       159 天前
    xlswriter 简直无敌,读取速度快就罢了 ,内存占用低到离谱,真的夸张,
    100 多万的电话号 + 各种参数,一点压力没有,用 PhpSpreadsheet 内存 4g 都不够,读取还贼慢
    maigebaoer
        9
    maigebaoer  
       159 天前 via Android
    等看百万级测试结果
    manhere
        10
    manhere  
       159 天前
    多工作表呢?
    edk24
        11
    edk24  
    OP
       159 天前
    @manhere 这个库考虑的是单表数据的导入与导出, 这个场景最多。宗旨是简单使用,快速实现导入导出数据的功能。

    如果涉及多工作表就会变得复杂起来,这样更推荐 PhpSpreadsheet 高度 diy

    谢谢你的反馈,回头我把涉及多工作表无法实现的内容写到 README 中
    edk24
        12
    edk24  
    OP
       159 天前
    @maigebaoer 多谢大佬的关注,上面有测试 10w 行 100 列的测试结果。 已经是优化后 csv 的结果了。

    这个库的初衷是为了能快速的实现导入导出功能, 易用性是我主要关注的内容,十万左右数据量足够覆盖大多数场景了。 字段少一点的话 100w 估计也挺快的, 问题就是内存占用会比较大。

    csv 是靠 fgetcsv 实现的,这个是 php 原生提供的,优化的空间我能想到的就是使用回调来读取每一行处理。这样可以减少内存的使用。

    对性能速度内存有特殊要求的话,我更推荐上面朋友们推荐的 xlswriter , 使用也比较简单 速度快 内存占用低。 只是需要安装扩展来实现。
    codebs
        13
    codebs  
       159 天前
    @edk24 xlswriter 自己一次性生成几个 php 版本的 so 文件,上传即用,非常香
    edk24
        14
    edk24  
    OP
       159 天前
    @Xinu 确实,我在做 100000row and 100column 时,4G 内存都不够 `PhpSpreadsheet` 吃。 csv 我还是依靠 fputcsv 实现可用的, 但也会占到 1.6GB 左右(全部读取存变量, 可能回调处理每一行效果更优)。

    我这个库还是关注易用性方面吧 😭,无需安装三方扩展 composer 一句话安装, 一行代码搞定导出 也算是个小优点。
    edk24
        15
    edk24  
    OP
       159 天前
    @codebs 这个可以有,常用的架构都编译来放着。 问一个问题比如 php7.x 和 php8.x 都可以用同一个编译的 so 库吗?
    cpu 架构一致的情况下
    coderzhangsan
        16
    coderzhangsan  
       158 天前
    项目中也用了不少 excel 扩展包,性能都不怎么好;很多数据导出,并不需要复杂的模板结构,csv 就够用了,简单封装下即可,实在不行直接上 xlswriter 。
    codebs
        17
    codebs  
       158 天前   ❤️ 1
    @edk24 不可以,每个版本都生成一下。需要在哪个版本用添加一下插件就好了,省得每次都安装
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3494 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:43 · PVG 18:43 · LAX 02:43 · JFK 05:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.