Drawer.php 5.33 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
<?php
/**
 * Created by PhpStorm.
 * User: Zero
 * Date: 2020/7/27
 * Time: 11:44
 */

namespace Meibuyu\Micro\Tools;

use Exception;
use Hyperf\Contract\ConfigInterface;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class Drawer
{

    /**
     * @var ConfigInterface
     */
    protected $config;

    private $rootPath;

    private $savePath = '';

    public function __construct()
    {
        $this->config = container(ConfigInterface::class);
        $this->rootPath = $this->config->get('server.settings.document_root', BASE_PATH . '/public');
    }

    private function parseImagePath($imagePath)
    {
        if (strstr($imagePath, 'http') !== false) {
            $imagePath = $this->downloadWebImage($imagePath);
        }
        return $imagePath;
    }

    /**
     * @param string $url
     * @param string $path
     * @return string
     */
    public function downloadWebImage($url, $path = null)
    {
49 50
        // excel画图中下载图片时对图片名做urlencode处理,防止中文名不能正常画图片的bug
        $filename = urlencode(pathinfo($url, PATHINFO_BASENAME));
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
        $url = $this->parseUrl($url);
        $path = $this->rootPath . '/download/images/' . ($path ?: $this->savePath);
        if (!is_dir($path)) {
            // 判断路径是否存在,不存在,则创建
            mkdir($path, 0777, true);
        }
        $filePath = $path . '/' . $filename;
        if (!file_exists($filePath)) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
            $file = curl_exec($ch);
            curl_close($ch);

            $resource = fopen($path . '/' . $filename, 'a');
            fwrite($resource, $file);
            fclose($resource);
        }
        return $filePath;
    }

    private function parseUrl($url)
    {
        $url = rawurlencode($url);
        $url = str_replace("%3A", ":", $url);
        return str_replace("%2F", "/", $url);
    }

    /**
     * @param $imgPath
     * @param int $px
     * @return bool|string
     * @throws Exception
     */
    public function addBoard($imgPath, $px = 2)
    {
        $imgPath = $this->parseImagePath($imgPath);

        $imgPathInfo = pathinfo($imgPath);
        $filename = $imgPathInfo['filename']; // 图片名称
        $ext = $imgPathInfo['extension']; // 图片扩展名
        [$img_w, $img_h] = getimagesize($imgPath); // 图片大小

        $savePath = $this->rootPath . '/download/board';
        if (!is_dir($savePath)) {
            // 判断路径是否存在,不存在,则创建
            mkdir($savePath, 0777, true);
        }
        $imgNewPath = $savePath . '/' . $filename . '.' . $ext;
        if (file_exists($imgNewPath)) {
            return $imgNewPath;
        }

        switch ($ext) {
            case 'jpeg':
            case 'jpg':
                $img_create_func = 'imagecreatefromjpeg';
                $img_save_func = 'imagejpeg';
                break;
            case 'png':
                $img_create_func = 'imagecreatefrompng';
                $img_save_func = 'imagepng';
                break;
            case 'bmp':
                $img_create_func = 'imagecreatefrombmp';
                $img_save_func = 'imagebmp';
                break;
            case 'gif':
                $img_create_func = 'imagecreatefromgif';
                $img_save_func = 'imagegif';
                break;
            case 'vnd.wap.wbmp':
                $img_create_func = 'imagecreatefromwbmp';
                $img_save_func = 'imagewbmp';
                break;
            case 'xbm':
                $img_create_func = 'imagecreatefromxbm';
                $img_save_func = 'imagexbm';
                break;
            default:
                throw new Exception("图片类型不支持");
        }

        // 黑色背景图片
        $im = @imagecreatetruecolor(($img_w + $px), ($img_h + $px)) or die ("Cannot Initialize new GD image stream");
        // 为真彩色画布创建背景,再设置为透明
        $color = imagecolorallocate($im, 0, 0, 0);
        imagefill($im, 0, 0, $color);
        imageColorTransparent($im, $color);
        // 把图片放到黑色背景图片上。边框是1px
        $resource = $img_create_func($imgPath);
        imagecopy($im, $resource, $px / 2, $px / 2, 0, 0, $img_w, $img_h);

        $res = $img_save_func($im, $imgNewPath);

        imagedestroy($im);
        return $res ? $imgNewPath : false;
    }

    /**
     * 画图片
     * @param string $path 图片路径
     * @param int $h 图片高度
     * @param string $p 单元格索引
     * @param Worksheet $sheet
王源's avatar
王源 committed
158
     * @param int $boardPx
159
     */
王源's avatar
王源 committed
160
    public function draw2Excel($path, $h, $p, $sheet, $boardPx = 0)
161 162 163
    {
        try {
            $path = $this->parseImagePath($path);
王源's avatar
王源 committed
164 165
            if ($boardPx) {
                $path = $this->addBoard($path, $boardPx);
166 167 168 169 170 171 172 173 174 175 176 177 178 179
            }
            $drawing = new Drawing();
            $drawing->setPath($path)->setCoordinates($p)->setHeight($h)->setWorksheet($sheet);
        } catch (Exception $e) {
            put_log($e->getMessage());
        }
    }

    public function setSavePath($path)
    {
        $this->savePath = $path;
    }

}