带图片的Excel表格导入/Excel中png图片的获取

需求:Excel表格是学校的很多信息,包括基本信息,专业信息等,有多个sheet;需以此表格为依据导入到数据库生成一个学校;或者更新一个学校的信息;

难点: Excel表格中 学校的logo 是图片;是jpg,png,等格式;png格式是 如何正确获取到这张图片。

使用的第三方处理excel表格的库为:

\PhpOffice\PhpSpreadsheet

代码:

public static function importExcelWithImage($filePath, $startRow = 1)
    {
        $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
        if (!$reader->canRead($filePath))
        {
            $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
            // setReadDataOnly Set read data only 只读单元格的数据,不格式化 e.g. 读时间会变成一个数据等
            if (!$reader->canRead($filePath))
            {
                throw new NotFoundHttpException('不能读取Excel');
            }
        }

        $spreadsheet = $reader->load($filePath);
        $sheetCount = $spreadsheet->getSheetCount();// 获取sheet的数量

        // 获取所有的sheet表格数据
        $images = [];
        $excleDatas = [];
        $emptyRowNum = 0;
        for ($i = 0; $i < $sheetCount; $i++)
        {
            $currentSheet = $spreadsheet->getSheet($i); // 读取excel文件中的第一个工作表
            $allColumn = $currentSheet->getHighestColumn(); // 取得最大的列号
            $allColumn = Coordinate::columnIndexFromString($allColumn); // 由列名转为列数('AB'->28)
            $allRow = $currentSheet->getHighestRow(); // 取得一共有多少行

            $arr = [];
            for ($currentRow = $startRow; $currentRow <= $allRow; $currentRow++)
            {
                // 从第1列开始输出
                for ($currentColumn = 1; $currentColumn <= $allColumn; $currentColumn++)
                {
                    $cellObj = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow);
                    $type = $cellObj->getDataType();
                    $val = $cellObj->getValue();


                    $arr[$currentRow][] = trim($val);
                }

                // $arr[$currentRow] = array_filter($arr[$currentRow]);
                // 统计连续空行
                if (empty($arr[$currentRow]) && $emptyRowNum <= 50)
                {
                    $emptyRowNum++ ;
                }
                else
                {
                    $emptyRowNum = 0;
                }
                // 连续50行数据为空,不再读取后面行的数据,防止读满内存
                if ($emptyRowNum > 50)
                {
                    break;
                }
            }
            //开始处理图片

            foreach ($currentSheet->getDrawingCollection() as $drawing) {
                if ($drawing instanceof MemoryDrawing) {
                    switch ($drawing->getMimeType()) {
                        case MemoryDrawing::MIMETYPE_PNG :
                            $extension = 'png';
                            break;
                        case MemoryDrawing::MIMETYPE_GIF :
                            $extension = 'gif';
                            break;
                        case MemoryDrawing::MIMETYPE_JPEG :
                            $extension = 'jpg';
                            break;
                    }


                    $gdRes = $drawing->getImageResource();
                    ob_start();
                    if($extension == 'png'){
                        //设置透明
                        imagesavealpha($gdRes,true);
                    }

                    call_user_func(
                        $drawing->getRenderingFunction(),
                        $gdRes //$drawing->getImageResource()
                    );

                    $imageContents = ob_get_contents();
                    ob_end_clean();

                } else {
                    $zipReader = fopen($drawing->getPath(), 'r');
                    $imageContents = '';
                    while (!feof($zipReader)) {
                        $imageContents .= fread($zipReader, 1024);
                    }
                    fclose($zipReader);
                    $extension = $drawing->getExtension();
                }

                //列从 0开始,行从1开始 和数据保持一致
                list($imageStartColumn, $imageStartRow) = Coordinate::coordinateFromString($drawing->getCoordinates());
                $imageStartColumn = Coordinate::columnIndexFromString($imageStartColumn) -1 ;

                $folder_name = sys_get_temp_dir();

                $myFileName = time() . '_' . mt_rand(100000, 999999) . '.' . $extension;

                $images[] = $arr[$imageStartRow][$imageStartColumn] = $folder_name.'/'.$myFileName;
                file_put_contents("{$folder_name}/{$myFileName}", $imageContents);

            }



            $excleDatas[$i] = $arr; // 多个sheet的数组的集合
        }

        return array('data' => $excleDatas, 'images' => $images);

    }

注意的地方:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
// setReadDataOnly Set read data only 只读单元格的数据,不格式化 e.g. 读时间会变成一个数据等

不要对 $read 进行 setReadDataOnly的设置为true 这样做会使下边无法获取到图片资源,也会对时间等内容产生影响;

难点的解决代码:

$gdRes = $drawing->getImageResource();
ob_start();
if($extension == 'png'){
    //设置透明
    imagesavealpha($gdRes,true);
}

解决的思路:

1. 查看PhpSpreadsheet 的文档查找对 png格式特殊处理的函数;结果没有找到!

2. 断点调试代码打印 $gdRes 对象;结果发现它就是 gd库的图片资源类型;这就说明可以使用原始的gd库的方法 imagesavealpha()来设置透明了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值