秒读 Excel 百万数据(第一篇)

读取前的准备工作

1. 文件类型属于 .xls 、.xlsx,需要用办公软件 WPS 或 Office 将文件另存为 .csv 类型。不能直接重命名修改文件类型,直接重命名修改文件类型会导致数据格式不兼容,Windows上可以正常打开阅读,Linux上读取数据会出现数据转码不成功,无法正常读取数据

2. Excel文件类型必须是 .csv

正式开始(主要代码在后面)

服务器配置:\
CPU: 4核\
内存: 16 GiB\
带宽: 6Mbps

<?php

ini_set('memory_limit', -1);

//开始运行时间
$stime = microtime(true);

//开始位置获取(内存)
$start_memory = memory_get_usage();

//文件路径
$filePath = '你的文件路径';

//传入文件路径
$readerCsv = new ReaderCsv($filePath);

//读取csv文件
$readerCsv->readCsv();

//获取Excel数据
$excelData = $readerCsv->getExcelData();

//结束运行时间
$etime     = microtime(true);
$timeUsage = $etime - $stime;

//末尾位置获取
$end_memory = memory_get_usage();
$use_memory = $end_memory - $start_memory;
$use_memory = $use_memory / 1024 / 1024;

dd('共读取数据: '.$readerCsv->getRow().'行', '共耗时: '.$timeUsage.'秒', '共消耗内存: '.$use_memory.'MB');


运行结果

Excel表总列数:31

104w数据

image.png

80w数据

image.png

60w数据

image.png

40w数据

image.png

20w数据

image.png

主要代码

<?php

namespace App\Excel;

class ReaderCsv
{

    /**
     * 数组键值
     * @var int
     */
    protected $row = 0;

    /**
     * Excel源数据
     * @var array
     */
    protected $excelData = [];

    /**
     * 文件路径
     * @var
     */
    protected $path;

    /**
     * ReaderCsv constructor.
     * @param $path
     */
    public function __construct($path)
    {
        $this->path = $path;
    }

    /**
     * 读取CSV文件
     */
    public function readCsv()
    {
        //数组键值
        $row = $this->row;

        //Excel数组
        $excelData = [];

        //打开文件
        $file = fopen($this->path, 'r');

        //从文件指针中读入一行并解析 CSV 字段
        //fgetcsv 解析读入的行并找出 CSV 格式的字段然后返回一个包含这些字段的数组。
        while ($data = fgetcsv($file)) {
            //统计一行数据有多少列
            $columnSize = count($data);

            for ($i = 0; $i < $columnSize; $i++) {
                //转换字符的编码 && 赋值Excel源数据
                $excelData[$row][$i] = mb_convert_encoding(
                    $data[$i],
                    'UTF-8',
                    'gb2312'
                );
            }
            $row++;
        }

        $this->row = $row;

        //关闭一个已打开的文件指针
        fclose($file);

        $this->excelData = $excelData;
    }

    /**
     * 获取Excel源数据
     * @return array
     */
    public function getExcelData()
    {
        return $this->excelData;
    }

    /**
     * 获取总行数
     * @return int
     */
        public function getRow()
    {
        return $this->row;
    }
}


最后

如果业务需要读取大Excel文件建议使用上面的方法,小的Excel文件还是建议使用PhpSpreadsheet

这篇说的是一次读取整个Excel文件(还是会有不足的地方),后续会更新第二篇按照“块”的方式读取。

第一次分享,有不好的地方请多多见谅~_~

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 8
Jourdon

可以试试这个 ,https://github.com/rap2hpoutre/fast-excel

我记得之前在社区里有个详细的对比,现在找不到了。

2周前 评论

标题改成秒读 CSV 比较好,毕竟 excel 生成的文件并不全是 csv 格式。

2周前 评论
Hanson
2周前 评论
97Boy

@Hanson 自己动手写是最好的

2周前 评论
97Boy

@qufo 下一篇发表后再改 :sweat_smile:

2周前 评论
97Boy

@Jourdon 我会去了解了解

2周前 评论

标题改成秒读 TXT 比较好,毕竟 csv 其实就是格式化的 txt。秒读excel文件这个就不太现实了,别说读取,你这百万行数据写进去,直接就爆表了。csv 的读写速度是跟 txt一样的,千万条数据都是秒的

2周前 评论
97Boy

@zulien 我觉得标题没必要改,CSV是纯文本格式并且Excel支持CSV格式文件是属于Excel的一种,我在文章中只分享了读取CSV,至于该怎么将数据写入数据表需要自己想,一般都不会直接将百万数据写入表中

2周前 评论
zulien 2周前
97Boy (作者) (楼主) 2周前

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!