批量生成带有二维码(含logo)的分享海报

前端页面

前端代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>海报生成</title>
    <style>
        html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
            margin: 0;
            padding: 0;
            border: 0;
            font-size: 100%;
            font: inherit;
            vertical-align: baseline
        }

        article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
            display: block
        }

        body {
            line-height: 1
        }

        ol, ul {
            list-style: none
        }

        blockquote, q {
            quotes: none
        }

        blockquote:before, blockquote:after, q:before, q:after {
            content: '';
            content: none
        }

        table {
            border-collapse: collapse;
            border-spacing: 0
        }

    </style>

    <style>
        * {
            box-sizing: border-box;
        }

        body {
            font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
            color: white;
            font-size: 12px;
            background: #333333;
        }

        form {
            background: #111;
            width: 500px;
            margin: 50px auto;
            border-radius: 0.4em;
            border: 1px solid #191919;
            overflow: hidden;
            position: relative;
            box-shadow: 0 5px 10px 5px rgba(0, 0, 0, 0.2);
        }

        form:after {
            content: "";
            display: block;
            position: absolute;
            height: 1px;
            width: 100px;
            left: 20%;
            background: linear-gradient(to right, #111111, #444444, #b6b6b8, #444444, #111111);
            top: 0;
        }

        form:before {
            content: "";
            display: block;
            position: absolute;
            width: 8px;
            height: 5px;
            border-radius: 50%;
            left: 34%;
            top: -7px;
            box-shadow: 0 0 6px 4px #fff;
        }

        .inset {
            padding: 20px;
            border-top: 1px solid #19191a;
        }

        form h1 {
            font-size: 18px;
            text-shadow: 0 1px 0 black;
            text-align: center;
            padding: 15px 0;
            border-bottom: 1px solid black;
            position: relative;
        }

        form h1:after {
            content: "";
            display: block;
            width: 250px;
            height: 100px;
            position: absolute;
            top: 0;
            left: 50px;
            pointer-events: none;
            transform: rotate(70deg);
            background: linear-gradient(50deg, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0));
        }

        label {
            color: #666;
            display: block;
            padding-bottom: 9px;
        }

        input[type=text],
        input[type=password] {
            width: 100%;
            padding: 8px 5px;
            background: linear-gradient(#1f2124, #27292c);
            border: 1px solid #222;
            box-shadow: 0 1px 0 rgba(255, 255, 255, 0.1);
            border-radius: 0.3em;
            margin-bottom: 20px;
        }

        label[for=remember] {
            color: white;
            display: inline-block;
            padding-bottom: 0;
            padding-top: 5px;
        }

        input[type=checkbox] {
            display: inline-block;
            vertical-align: top;
        }

        .p-container {
            padding: 0 20px 20px 20px;
        }

        .p-container:after {
            clear: both;
            display: table;
            content: "";
        }

        input[type=submit] {
            padding: 5px 20px;
            border: 1px solid rgba(0, 0, 0, 0.4);
            text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
            box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 10px 10px rgba(255, 255, 255, 0.1);
            border-radius: 0.3em;
            background: #0184ff;
            color: white;
            display: block;
            margin: 0 auto;
            /*float: right;*/
            font-weight: bold;
            cursor: pointer;
            font-size: 13px;
        }

        .button {
            padding: 5px 20px;
            border: 1px solid rgba(0, 0, 0, 0.4);
            text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
            box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 10px 10px rgba(255, 255, 255, 0.1);
            border-radius: 0.3em;
            background: #0184ff;
            color: white;
            display: block;
            margin: 0 auto;
            /*float: right;*/
            font-weight: bold;
            cursor: pointer;
            font-size: 13px;
        }

        input[type=submit]:hover {
            box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 -10px 10px rgba(255, 255, 255, 0.1);
        }

        input[type=text]:hover,
        input[type=password]:hover,
        label:hover ~ input[type=text],
        label:hover ~ input[type=password] {
            background: #27292c;
        }

    </style>

</head>

<body>

<form method="post" action="/index/index/toImportTheUrl" enctype="multipart/form-data">
    <h1>海报生成</h1>
    <div class="inset">
        <p>
            <label style="color: red;">LOGO图</label>
            <input type="file" name="logo"/>
        </p>
        <br>
        <p>
            <label style="color: red;">海报底图</label>
            <input type="file" name="posters"/>
        </p>
        <br>
        <p>
            <label style="color: red;">表格上传</label>
            <input type="file" name="url"/>
        </p>
        <br>
        <p>
            <label style="color: red;">上传人</label>
            <input type="text" name="name" placeholder="lys"/>
        </p>
        <p>
            <label style="color: red;">生成日期</label>
            <input type="text" name="date" placeholder="0522"/>
        </p>
        <p>
            <label style="color: red;">起始序号</label>
            <input type="text" name="sequence" placeholder="1001"/>
        </p>
    </div>
    <p class="p-container">
        <input id="btn1" type="submit" onclick="threeFn()" value="提交">
    </p>
</form>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
    function threeFn(){
        $("#btn1").attr("style","display:none;");
    }
</script>

</html>

 

PHP代码

<?php

namespace app\index\controller;

use think\Controller;

class Index extends Controller
{
    public function index()
    {
        return view('index');
    }

    /**
     * $date 生成日期
     * $sequence 起始序号
     * $_FILES ['logo'] LOGO图
     * $_FILES ['posters'] 海报底图
     * $_FILES ['url'] excel表格
     */
    public function toImportTheUrl()
    {
        $name = $this->request->request('name');
        $date = $this->request->request('date');
        $sequence = $this->request->request('sequence');
        if (empty ($_FILES ['logo'] ['name']) || empty ($_FILES ['posters'] ['name']) || empty ($_FILES ['url'] ['name']) || empty($name) || empty($date) || empty($sequence)) {
            $this->error('数据不可为空');
        }
        // 存储logo图
        if (!empty ($_FILES ['logo'] ['name'])) { // 判断文件是否为空
            $logo_file = $_FILES ['logo'] ['tmp_name'];
            // 重设置文件名
            // $logofilename = 'logo' . substr($_FILES ['logo'] ['name'], stripos($_FILES ['logo'] ['name'], '.'));
            $logofilename = 'logo.png';
            $logopath = 'img/' . $logofilename; // 设置移动路径
            move_uploaded_file($logo_file, $logopath);
        }
        // 存储海报底图
        if (!empty ($_FILES ['posters'] ['name'])) { // 判断文件是否为空
            $posters_file = $_FILES ['posters'] ['tmp_name'];
            // 重设置文件名
            // $postersfilename = 'canvas' . substr($_FILES ['posters'] ['name'], stripos($_FILES ['posters'] ['name'], '.'));
            $postersfilename = 'canvas.png';
            $posterspath = 'img/' . $postersfilename; // 设置移动路径
            move_uploaded_file($posters_file, $posterspath);
        }


        if (!empty ($_FILES ['url'] ['name'])) { // 判断文件是否为空
            $tmp_file = $_FILES ['url'] ['tmp_name'];
            // 判断文件类型
            $file_types = explode(".", $_FILES ['url'] ['name']);
            $file_type = $file_types [count($file_types) - 1];
            // 判别是不是.xls文件,判别是不是excel文件
            if (strtolower($file_type) != "xls" && strtolower($file_type) != "xlsx" && strtolower($file_type) != "csv") {
                $this->error('不是Excel文件,重新上传', '/index/index/index');
            }
            // 重设置文件名
            $filename = time() . substr($_FILES ['url'] ['name'], stripos($_FILES ['url'] ['name'], '.'));
            $path = 'excel/' . $filename; // 设置移动路径

            move_uploaded_file($tmp_file, $path);

            if ($file_type == 'xls') {
                $type = 'Excel5'; // 后缀如果是 xls 的话用E xcel5 是 xlsx 用 Excel2007
            } elseif ($file_type == 'xlsx') {
                $type = 'Excel2007'; // 后缀如果是 xls 的话用E xcel5 是 xlsx 用 Excel2007
            } elseif ($file_type == 'csv') {
                $type = 'CSV';
            }

            $xlsReader = \PHPExcel_IOFactory::createReader($type);
            $xlsReader->setReadDataOnly(true);
            $xlsReader->setLoadSheetsOnly(true);
            $Sheets = $xlsReader->load($path);
            // 开始读取上传到服务器中的Excel文件,返回一个二维数组
            $dataArray = $Sheets->getSheet(0)->toArray();
            unset($dataArray['0']);
            foreach ($dataArray as $k => $v) {
                $dataArray[$k] = $v['3'];
            }
            // 调用方法生成海报
            $fileList = $this->generatePoster($dataArray, $sequence, $name, $date);
            // 删除二维码
            @unlink('Qr_code.png');
            // 删除Logo二维码
            @unlink('Logo_qr_code.png');

            /*****   多文件压缩开始   *****/
            // 生成的压缩包所在的位置路径
            $filename = "alg/" . $name . '-' . $date . ".zip";
            // 声明ZipArchive类
            $zip = new \ZipArchive();
            // 打开压缩包,没有则创建
            $zip->open($filename, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
            foreach ($fileList as $file) {
                // 向压缩包中添加文件
                $zip->addFile($file, basename($file));
            }
            // 关闭压缩包
            $zip->close();
            /*****   多文件压缩结束   *****/

            // 删除上传的文件
            @unlink($_SERVER['DOCUMENT_ROOT'] . '/' . pathinfo($path)['dirname'] . '/' . pathinfo($path)['basename']);
        }

        // 设置需要删除的文件夹
        $path = $_SERVER['DOCUMENT_ROOT'] . '/' . pathinfo('poster/' . $date)['dirname'] . '/' . pathinfo('poster/' . $date)['basename'];
        // 删除文件夹及子文件
        if (is_dir($path)) {
            // 遍历一个文件夹所有文件并返回数组
            $poster_arr = scandir($path);
            foreach ($poster_arr as $val) {
                //排除目录中的.和..
                if ($val != "." && $val != "..") {
                    //如果是目录则递归子目录,继续操作
                    if (is_dir($path . '/' . $val)) {
                        //子目录中操作删除文件夹和文件
                        deldir($path . '/' . $val . '/');
                        //目录清空后删除空文件夹
                        @rmdir($path . '/' . $val . '/');
                    } else {
                        //如果是文件直接删除
                        unlink($path . '/' . $val);
                    }
                }
            }
            @rmdir($path);
        }
        $url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . '/' . $filename;

        echo "<script> alert('下载压缩包'); </script>";
        echo "<meta http-equiv='Refresh' content='0;URL=$url'>";

        $this->success('海报生成完毕,正在下载!', 'index/index/index');
    }

    /**
     * 生成二维码 Logo二维码 带Logo二维码海报
     * $url 二维码内容
     * $sequence // 起始序号
     * $name // 上传人
     * $date // 日期
     */
    public function generatePoster($url, $sequence, $name, $date)
    {
        header("Content-type: image/png");
        // 加载phpqrcode类文件
        include('phpqrcode/phpqrcode.php');
        // 声明qrcode类
        $qrcode = new \QRcode();

        $arr = [];

        foreach ($url as $value) {

            /*****   二维码生成开始   *****/
            // 二维码内容
            // $value = $url;
            // 容错级别
            $errorCorrectionLevel = 'H';
            // 生成二维码大小
            $matrixPointSize = 11;
            // 生成二维码图片名(含路径)
            $filename = 'Qr_code.png';
            // 生成二维码
            $qrcode->png($value, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
            /*****   二维码生成结束   *****/

            /*****   Logo二维码生成开始   *****/
            // 准备好的logo图片
            $logo = 'img/logo.png';
            // logo图是否存在
            if (file_exists($logo)) {
                // 目标图象连接资源
                $QR = imagecreatefromstring(file_get_contents($filename));
                // 源图象连接资源
                $logo = imagecreatefromstring(file_get_contents($logo));
                // 二维码图片宽度
                $QR_width = imagesx($QR);
                // 二维码图片高度
                // $QR_height = imagesy($QR);
                // logo图片宽度
                $logo_width = imagesx($logo);
                // logo图片高度
                $logo_height = imagesy($logo);
                // 组合之后logo的宽度(占二维码的1/5)
                $logo_qr_width = $QR_width / 4;
                // logo的宽度缩放比(本身宽度/组合后的宽度)
                $scale = $logo_width / $logo_qr_width;
                // 组合之后logo的高度
                $logo_qr_height = $logo_height / $scale;
                // 组合之后logo左上角所在坐标点
                $from_width = ($QR_width - $logo_qr_width) / 2;
                // 重新组合图片并调整大小
                // imagecopyresampled() 将一幅图像(源图象)中的一块正方形区域拷贝到另一个图像中
                imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
            }
            // 输出图片 (这里注意是本地目录)
            imagepng($QR, 'Logo_qr_code.png');
            // 销毁一图像
            imagedestroy($QR);
            imagedestroy($logo);
            // 删除二维码
            // @unlink('Qr_code.png');
            /*****   Logo二维码生成结束   *****/

            /*****   海报和Logo二维码合成开始   *****/
            // 海报底图路径
            $posters_path = 'img/canvas.png';
            // 覆盖的Logo二维码地址
            $logo_path = 'Logo_qr_code.png';
            //创建图片的实例
            $posters = imagecreatefromstring(file_get_contents($posters_path));
            $logo = imagecreatefromstring(file_get_contents($logo_path));
            // 获取覆盖图图片的宽高
            list($posters_w, $logo_h) = getimagesize($logo_path);
            // 将覆盖图复制到目标图片上,最后个参数100是设置透明度(100是不透明),这里实现不透明效果
            imagecopymerge($posters, $logo, 245, 395, 0, 0, $posters_w, $logo_h, 100);
            // 删除Logo二维码
            // @unlink('Logo_qr_code.png');
            // 判断文件是否存在 不存在则生成
            @mkdir('poster/' . $date);
            // 根据需要生成相应的图片
            imagepng($posters, 'poster/' . $date . '/' . $name . '-' . $date . '-' . $sequence . '.png');
            /*****   海报和Logo二维码合成结束   *****/
            $arr[] = 'poster/' . $date . '/' . $name . '-' . $date . '-' . $sequence . '.png';
            $sequence++;
        }
        return $arr;
    }


}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

withoutfear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值