PHP 导入xlsx文件,附带图片,并将图片上传到OSS

    /**
     * 商品导入
     * @return void
     */
    public function import()
    {
        $file = $this->request->file('file');

        if (!$file) return app('json')->fail('请上传EXCEL文件');
        $file = is_array($file) ? $file[0] : $file;
        validate(["file|文件" => ['fileExt' => 'xlsx,xls',]])->check(['file' => $file]);

        $upload = UploadService::create(1);
        $ret = $upload->to('excel')->move('file');
        if ($ret === false) return app('json')->fail($upload->getError());
        $res = $upload->getUploadInfo();
        $path = rtrim(public_path(), '/') . $res['dir'];

        $field_list = ['store_name', 'cate_id', 'sh_cate_id', 'brand_id', 'unit_name', 'keyword', 'store_info',
            'price', 'cost', 'ot_price', 'stock', 'bar_code', 'weight', 'volume', 'sort',
            'image', 'slider_image', 'content', 'content_text', 'delivery_way', 'delivery_free'];

        $file_path = $path; //包含图片的Excel文件
        //导入数据库
        $result = $this->readexcel1($field_list, $file_path);
        if ($result !== true) {
            return app('json')->fail($result);
        } else {
            return app('json')->success('导入成功');
        }

    }

    // 获取excel表格的图片
    public function readexcel1($field_list, $file)
    {
        $merId = $this->request->merId();
        $imageFilePath = '/uploads/imgssss'; //图片本地存储的路径
        $path = public_path($imageFilePath);
        if (!is_dir($path)) { //如果目录不存在则递归创建
            mkdir($path, 0777, true);
        }
        if (!$file) return false;
        $pathInfo = pathinfo($file, PATHINFO_EXTENSION);

        if (!$pathInfo || $pathInfo != "xlsx") throw new ValidateException('必须上传xlsx格式文件');
        $objRead = IOFactory::createReader('Xlsx');
        $objSpreadsheet = $objRead->load($file);
        $objWorksheet = $objSpreadsheet->getSheet(0);
        $data = $objWorksheet->toArray();

        Db::startTrans();
        try {
            $all_data = [];
            foreach ($data as $key => $value) {
                $data_arr = [];
                foreach ($field_list as $field_key => $field_value) {
                    $data_arr[$field_value] = trim($value[$field_key]);
                }
                $all_data[] = $data_arr;
            }
            unset($all_data[0]);
            unset($all_data[1]);
            //如果数据超过50条数据则 提示请拆分数据导入
            if (count($all_data) > 50) {
                return app('json')->fail('数据超过50条数据请拆分数据导入');
            }
            foreach ($all_data as $key => &$value) {
                //检查必填项是否都填写
                if (!$value['store_name'] || !$value['cate_id'] || !$value['sh_cate_id']
                    || !$value['unit_name'] || !$value['price'] || !$value['cost'] || !$value['ot_price'] || !$value['stock']) {
                    throw new ValidateException('第' . ($key + 1) . '行数据有必填项未填写');
                }
                //查找平台商品分类
                $value['cate_id'] = $this->getCateId($value['cate_id']);
                //查找商户商品分类
                $value['store_product_cate'] = $this->getProductCateId($value['sh_cate_id'], $merId);
                //查找商品品牌id
                $brand_id = '';
                if ($value['brand_id']) {
                    $brand_id = (new StoreBrand())->where('brand_name', '=', $value['brand_id'])->value('brand_id');
                    if (empty($brand_id)) {
                        throw new ValidateException($value['brand_id'] . '品牌不存在');
                    }
                }
                $value['brand_id'] = $brand_id;
                unset($all_data[$key]['sh_cate_id']);
            }
            foreach ($objSpreadsheet->getWorksheetIterator() as $worksheet) {
                foreach ($worksheet->getDrawingCollection() as $drawing) {
                    list($startColumn, $startRow) = Coordinate::coordinateFromString($drawing->getCoordinates());//获取图片所在行和列
                    //将图片保存到临时文件
                    $imagePath = $drawing->getPath();
                    $md5 = md5(uniqid()) . '.' . $drawing->getExtension();
                    $newImagePath = $path . $md5;
                    copy($imagePath, $newImagePath);//复制图片到新路径
                    if ($imagePath) {
                        //将图片上传到OSS
                        $ossPath = $this->uploadToOss($newImagePath);
                        // 删除临时文件
                        unlink($newImagePath);
                    }
                    $startColumn = $this->ABC2decimal($startColumn);//由于图片所在位置的列号为字母,转化为数字
                    //将数据存储到附件表
                    $data_new = [
                        'attachment_category_id' => 0,
                        'attachment_name' => $md5,
                        'attachment_src' => $ossPath['info']['url']
                    ];
                    $this->systemAttachment->create(3, $merId, $merId, $data_new);
                    //把图片插入到数组中
                    if ($startColumn == 15) {
                        $all_data[$startRow - 1]['image'] .= $data_new['attachment_src'] . ',';
                    }
                    if ($startColumn == 16) {
                        $all_data[$startRow - 1]['slider_image'] .= $data_new['attachment_src'] . ',';
                    }
                    if ($startColumn == 17) {
                        $all_data[$startRow - 1]['content'] .= $data_new['attachment_src'] . ',';
                    }
                }
            }

            foreach ($all_data as $key => &$value) {
                $value['image'] = rtrim($value['image'], ',');
                $value['slider_image'] = rtrim($value['slider_image'], ',');
                $value['content'] = rtrim($value['content'], ',');
                //商品详情拼接
                $content = explode(',', $value['content']);
                $content_detail = '<p>';
                foreach ($content as $k => $v) {
                    $content_detail .= '<img src="' . $v . '"/>';
                }
                $content_detail .= $value['content_text'];
                $content_detail .= '</p>';
                $value['content'] = $content_detail;
            }

            $store_spu = [];
            $store_product_content = [];
            $store_product_attr_value = [];
            $store_product_cate = [];
            $new_sku = [];
            foreach ($all_data as $k => $v) {
                if ($v['store_name'] != '') {
                    //产品表
                    $id = Db::name('store_product')->insertGetId([
                        'store_name' => $v['store_name'],
                        'cate_id' => $v['cate_id'],
                        'brand_id' => $v['brand_id'],
                        'unit_name' => $v['unit_name'],
                        'keyword' => $v['keyword'],
                        'store_info' => $v['store_info'],
                        'spec_type' => 0,
                        'sort' => is_numeric($v['sort']) ? $v['sort'] : '',
                        'slider_image' => $v['slider_image'],
                        'price' => $v['price'],
                        'cost' => $v['cost'],
                        'ot_price' => $v['ot_price'],
                        'stock' => $v['stock'],
                        'image' => $v['image'],
                        'mer_id' => $merId,
                        'is_show' => 0,
                        'status' => 1,
                        'temp_id' => 7,
                        'delivery_way' => $v['delivery_way'] ?? '1,2',
                        'delivery_free' => $v['delivery_free'] ?? 0,
                    ]);
                    //产品搜索信息表
                    $store_spu[] = [
                        'mer_id' => $merId,
                        'product_id' => $id,
                        'store_name' => $v['store_name'],
                        'keyword' => $v['keyword'],
                        'price' => $v['price'],
                        'ot_price' => $v['ot_price'],
                        'rank' => is_numeric($v['sort']) ? $v['sort'] : '',
                        'image' => $v['image'],
                    ];
                    //产品属性值表
                    $store_product_attr_value[] = [
                        'product_id' => $id,
                        'stock' => $v['stock'],
                        'image' => $v['image'],
                        'bar_code' => $v['bar_code'],
                        'cost' => $v['cost'],
                        'ot_price' => $v['ot_price'],
                        'price' => $v['price'],
                        'volume' => $v['volume'],
                        'weight' => $v['weight'],
                        'unique' => substr(md5('' . $id), 12, 11) . 0,
                    ];
                    //产品详情表
                    $store_product_content[] = [
                        'product_id' => $id,
                        'content' => $v['content'],
                    ];
                    //产品属性参数表
                    $attr = [
                        "attr" => [],
                        "attrValue" => [
                            [
                                "image" => "",
                                "price" => $v['price'],
                                "cost" => $v['cost'],
                                "ot_price" => $v['ot_price'],
                                "svip_price" => null,
                                "select" => "",
                                "stock" => $v['stock'],
                                "cdkey" => [],
                                "library_name" => "",
                                "library_id" => "",
                                "bar_code" => $v['bar_code'],
                                "bar_code_number" => "",
                                "weight" => $v['weight'],
                                "volume" => $v['volume']
                            ]
                        ],
                        "params" => []
                    ];
                    $new_sku[] = [
                        'product_id' => $id,
                        'result' => json_encode($attr, JSON_UNESCAPED_UNICODE),
                        'type' => 0
                    ];
                    //商户商品分类表
                    if (!empty($v['store_product_cate'])) {
                        foreach ($v['store_product_cate'] as $key => $item) {
                            //产品平台分类表
                            $store_product_cate[] = [
                                'product_id' => $id,
                                'mer_cate_id' => $item,
                                'mer_id' => $merId
                            ];
                        }
                    }
                }
            }

            (new Spu())->saveAll($store_spu);
            (new ProductContent())->saveAll($store_product_content);
            (new ProductAttrValue())->saveAll($store_product_attr_value);
            (new ProductCate())->saveAll($store_product_cate);
            Db::name('store_product_attr_result')->insertAll($new_sku);

            Db::commit();
            $result = true;
        } catch (\Exception $exception) {
            Db::rollback();
            $result = '导入失败,信息:' . $exception->getMessage();
        }
        return $result;
    }

    /**
     * 上传图片到OSS
     */
    private function uploadToOss($filePath)
    {
        try {
            $format = strrchr($filePath, '.');
            $object = 'import_img/' . date('Ymd') . '/' . sha1(date('YmdHis', time()) . uniqid()) . $format;

            $accessKey = systemConfig('accessKey');
            $secretKey = systemConfig('secretKey');
            $make = app()->make(StorageRepository::class);
            $result = $make->getConfig(3, $accessKey);
            $ossClient = new OssClient($accessKey, $secretKey, $result['region']);

            $result = $ossClient->uploadFile($result['name'], $object, $filePath);

            return $result;
        } catch (OssException $e) {
            error_log("上传到OSS失败: " . $e->getMessage());
            return false;
        }
    }

    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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值