PHP中excel带图片数据导入

前提:有个需求需要实现带图片的excel数据导入数据库中,发现PHPExcel - Excel 操作库已经停止维护,在PHP8的版本中,有些语法不支持,报错一堆,改了一堆,又还有一堆。所以决定找个替代的扩展:phpoffice/phpspreadsheet

技术背景前提:

  1. ThinkPHP8.0
  2. php8.0.2nts
  3. "phpoffice/phpspreadsheet": "^1.20.0"

在composer.json中加入"phpoffice/phpspreadsheet": "^1.20.0"composer update,如果选择的phpoffice/phpspreadsheet版本不同,可能又有不同的坑存在,得进行一一排查。这里记录下。

实现步骤看代码注释部分,实现代码如下:

php 复制代码
    /**
     * 字母序列化为数字
     */
    public function ABC2decimal($abc)
    {
        $ten = 0;
        $len = strlen($abc);
        for ($i = 1; $i <= $len; $i++) {
            $char = substr($abc, 0 - $i, 1);//反向获取单个字符
            $int = ord($char);
            $ten += ($int - 65) * pow(26, $i - 1);
        }
        return $ten;
    }


    public function excel()
    {
        if ($file = request()->file('excel')) {
            try {
                $saveName = Filesystem::disk('public')->putFile('/static/upload/excels', $file);
                if (!is_file($saveName)) {
                    return json(['code' => 1, 'msg' => '文件不存在', 'data' => null]);
                }
                $ext = pathinfo($saveName, PATHINFO_EXTENSION);
                // xls不支持图片导入
                // if (!in_array($ext, ['xlsx', 'xls'])) {
                if (!in_array($ext, ['xlsx'])) {
                    return json(['code' => 1, 'msg' => '文件类型不正确', 'data' => null]);
                }
                // 有两种格式,xlsx和xls
                if ($ext == 'xlsx') {
                    $objReader = IOFactory::createReader('Xlsx');
                } else {
                    $objReader = IOFactory::createReader('Xls');
                }
                // 图片保存路径
                $imageFilePath1 = root_path() . '/public/'; // 图片保存目录
                $imageFilePath2 = 'static/upload/images/' . date("Ymd") . '/';
                $imageFilePath = $imageFilePath1 . $imageFilePath2;
                if (!file_exists($imageFilePath)) {
                    mkdir("$imageFilePath", 0777, true);
                }
                // 载入excel文件
                $excel = $objReader->load($saveName);
                // 读取第一张表
                $sheet = $excel->getActiveSheet();
                // 读取总行数
                $highestRow = $sheet->getHighestRow();
                // 读取第一张表转换成数组
                $data = $sheet->toArray();

                // 处理图片
                foreach ($sheet->getDrawingCollection() as $drawing) {
                    list($startColumn, $startRow) = Coordinate::coordinateFromString($drawing->getCoordinates());
                    $imageFileName = $drawing->getIndexedFilename();  // 获取文件名
                    switch ($drawing->getExtension()) {
                        case 'jpg':
                        case 'jpeg':
                            $source = imagecreatefromjpeg($drawing->getPath());
                            imagejpeg($source, $imageFilePath . $imageFileName);
                            break;
                        case 'gif':
                            $source = imagecreatefromgif($drawing->getPath());
                            imagegif($source, $imageFilePath . $imageFileName);
                            break;
                        case 'png':
                            $source = imagecreatefrompng($drawing->getPath());
                            imagepng($source, $imageFilePath . $imageFileName);
                            break;
                    }
                    $startColumn = $this->ABC2decimal($startColumn);
                    $data[$startRow - 1][$startColumn] = $imageFilePath2 . $imageFileName;
                }

                // 数据写入数据库
                $add_data = [];
                for ($i = 1; $i <= $highestRow - 1; $i++) {
                    $add_data[$i]['institution'] = $data[$i][0];
                    $add_data[$i]['name'] = $data[$i][1];
                    $add_data[$i]['sex'] = $data[$i][2];
                    $add_data[$i]['phone'] = $data[$i][3];
                    $add_data[$i]['id_type'] = $data[$i][4];
                    $add_data[$i]['id_no'] = $data[$i][5];
                    $add_data[$i]['occupation'] = $data[$i][6];
                    $add_data[$i]['job'] = $data[$i][7];
                    $add_data[$i]['skill_level'] = $data[$i][8];
                    $add_data[$i]['certificate_no'] = $data[$i][9];
                    $add_data[$i]['create_time'] = $data[$i][10];
                    $add_data[$i]['start_time'] = $data[$i][11];
                    $add_data[$i]['end_time'] = $data[$i][12];
                    $add_data[$i]['path'] = $data[$i][13];
                }

                // 数据插入数据库
                $success_count = Db::table('certificate')->insertAll($add_data);
                if ($success_count > 0) {
                    return json(['code' => 0, 'msg' => '数据插入成功', 'data' => null]);
                } else {
                    return json(['code' => 1, 'msg' => '数据插入失败', 'data' => null]);
                }
            } catch (\Exception $e) {
                return json(['code' => 1, 'msg' => $e->getMessage(), 'data' => null]);
            }
        } else {
            return json(['code' => 1, 'msg' => '上传文件不能为空', 'data' => null]);
        }
    }
相关推荐
韩立学长2 分钟前
【开题答辩实录分享】以《奇妙英语角小程序的设计与实现》为例进行答辩实录分享
小程序·php
爱吃甜品的糯米团子7 分钟前
详解 JavaScript 内置对象与包装类型:方法、案例与实战
java·开发语言·javascript
郝学胜-神的一滴28 分钟前
Linux下,获取子进程退出值和异常终止信号
linux·服务器·开发语言·c++·程序人生
AI科技星43 分钟前
张祥前统一场论动量公式P=m(C-V)误解解答
开发语言·数据结构·人工智能·经验分享·python·线性代数·算法
CodeByV1 小时前
【C++】继承
开发语言·c++
权泽谦2 小时前
用 Python 做一个天气预报桌面小程序(附源码 + 打包与部署指导)
开发语言·python·小程序
ftpeak2 小时前
《Rust+Slint:跨平台GUI应用》第八章 窗体
开发语言·ui·rust·slint
森语林溪2 小时前
大数据环境搭建从零开始(十七):JDK 17 安装与配置完整指南
java·大数据·开发语言·centos·vmware·软件需求·虚拟机
lsx2024062 小时前
HTML 音频(Audio)详解
开发语言
woshihonghonga2 小时前
【动手学深度学习】
开发语言·python