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]);
        }
    }
相关推荐
剩下了什么4 小时前
float32 与 float64 精度陷阱:如何在 Go 中避免错误使用
开发语言·后端·golang
指尖时光.4 小时前
Three.js 超全入门综合案例
开发语言·javascript·ecmascript
暴力求解5 小时前
Linux网络---传输层协议TCP(二)
linux·服务器·开发语言·网络·tcp/ip
吴声子夜歌5 小时前
Java面试题——基础(一)
java·开发语言
admin0055 小时前
Excel记账和财务软件记账哪个好?效率与准确率真实对比
excel·excel记账·财务软件记账·小微企业记账
小庞在加油5 小时前
WinDbg实战:QT/跨平台项目死锁与无响应问题排查指南
开发语言·qt·windbg·工具
Vae_Mars6 小时前
C#中的delegate委托
开发语言·c#
一直走下去-明6 小时前
简单的http抓包解包完整代码
开发语言·python
caimouse6 小时前
ReactOS 图形系统分析(51):元文件子系统 — metafile.c
c语言·开发语言
学习星球7 小时前
Solid.js 实战:拆解官方 RealWorld 项目
开发语言·javascript·vue.js