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]);
        }
    }
相关推荐
云和数据.ChenGuang40 分钟前
Ascend C 核心技术特性
c语言·开发语言
kyle~3 小时前
C++---value_type 解决泛型编程中的类型信息获取问题
java·开发语言·c++
NiNi_suanfa6 小时前
【Qt】Qt 批量修改同类对象
开发语言·c++·qt
小糖学代码6 小时前
LLM系列:1.python入门:3.布尔型对象
linux·开发语言·python
Data_agent7 小时前
1688获得1688店铺详情API,python请求示例
开发语言·爬虫·python
妖灵翎幺7 小时前
C++ 中的 :: 操作符详解(一切情况)
开发语言·c++·ide
Halo_tjn7 小时前
虚拟机相关实验概述
java·开发语言·windows·计算机
star _chen7 小时前
C++实现完美洗牌算法
开发语言·c++·算法
周杰伦fans8 小时前
pycharm之gitignore设置
开发语言·python·pycharm
weixin_462446238 小时前
【原创实践】python 获取节假日列表 并保存为excel
数据库·python·excel