vue实现下载二维码

点击button按钮实现下载二维码

html 复制代码
<el-button
                    slot="reference"
                    size="mini"
                    style="margin-bottom: 10px; margin-left: 0"
                    type="success"
                    @click="handleDownload(scope.row)"
                    >下载二维码</el-button
                  >
                </div>  

弹窗

html 复制代码
<el-dialog
      :title="下载二维码"
      :visible.sync="qrVisible"
      :close-on-click-modal="false"
      center
      width="800px"
    >
      <div class="qr-container">
        <div
          class="qr-section"
          v-if="currentRow.length > 0"
          :style="{textAlign: (currentRow.length === 1 ? 'center' : 'left')}"
        >
          <div class="qr-image" >
            <div id="qrCode"></div>
            <div class="qrCode-name">
              编号:{{
              currentRow[0].code + (currentRow.length < 2 ? '' : "-"+currentRow[0].number)
              }}
            </div>
          </div>
        </div>
        <div
          class="qr-section"
          v-if="currentRow.length > 1"
          :style="{textAlign: 'left'}"
        >
          <div class="qr-image">
            <div id="qrCode2"></div>
            <div class="qrCode-name">
              编号:{{currentRow[1].code + "-" + (currentRow[1].number ? currentRow[1].number : '') }}
            </div>
          </div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="downloadQrCode">下载</el-button>
        <el-button v-if="currentRow.length > 1" @click="downloadQrCode2">下载</el-button>
      </span>
    </el-dialog>

引入依赖

html 复制代码
import QRCode from "@keeex/qrcodejs-kx";
import html2canvas from "html2canvas";
html 复制代码
data(){
	return{
		currentRow: [{}],
		qrVisible: false,
	}
}
html 复制代码
 handleDownload(row) {
      //打开弹窗,并插入图片
      this.currentRow = row;
      this.qrVisible = true;
      //调用后端,也可以不调,目的是获取二维码下方的描述
      ListData(row.deviceId).then((res) => {
        if (res.retCode == 200) {
          this.currentRow = res.data;
          setTimeout(() => {
            document.getElementById("qrCode").innerHTML = "";
            new QRCode("qrCode", {
              width: 202,
              height: 202,
              text: res.data[0].mallUrl,
            });
            if (res.data.length > 1) {
              document.getElementById("qrCode2").innerHTML = "";
              new QRCode("qrCode2", {
                width: 202,
                height: 202,
                text: res.data[1].mallUrl,
              });
            }
          }, 200);
        }
      });
    },
    //下载图片
    downloadQrCode() {
      //不可以调整图片大小
      /*html2canvas(this.$refs.addImage, { useCORS: true }).then((canvas) => {
        // this.$refs.addImage.append(canvas);
        // debugger
        let link = document.createElement("a");
        link.href = canvas.toDataURL();
        link.setAttribute("download", this.currentRow.deviceCode + "-1.png");
        link.style.display = "none";
        document.body.appendChild(link);
        link.click();
      });*/
      this.downloadQrCodes("qrCode",
        this.currentRow[0].deviceCode +
        (this.currentRow.length < 2 ?  "" : "-"+this.currentRow[0].number) );

    },
    //下载图片
    downloadQrCode2() {
      //不可以调整图片大小
     /* html2canvas(this.$refs.addImage2, { useCORS: true }).then((canvas) => {
        // this.$refs.addImage.append(canvas);
        let link = document.createElement("a");
        link.href = canvas.toDataURL();
        link.setAttribute("download", this.currentRow.deviceCode + "-2.png");
        link.style.display = "none";
        document.body.appendChild(link);
        link.click();
      });*/
      this.downloadQrCodes("qrCode2",
        this.currentRow[1].deviceCode +"-"+
        (this.currentRow[1].number ? this.currentRow[1].number : "") );
    },
    downloadQrCodes(elementId, fileName) {
      //不包含文字
     /* const element = document.getElementById(elementId);
      html2canvas(element, { useCORS: true }).then((canvas) => {
        const scaledCanvas = document.createElement('canvas');
        scaledCanvas.width = 300;
        scaledCanvas.height = 300;
        const ctx = scaledCanvas.getContext('2d');
        ctx.drawImage(canvas, 0, 0, 300, 300);
        const link = document.createElement("a");
        link.download = fileName;
        link.href = scaledCanvas.toDataURL("image/png");
        link.click();
      });*/

      // 包含文字
      const element = document.getElementById(elementId);
      html2canvas(element, { useCORS: true }).then((canvas) => {
        const canvasSize = 400; // 设置画布尺寸为正方形
        const scaledCanvas = document.createElement('canvas');
        scaledCanvas.width = canvasSize;
        scaledCanvas.height = canvasSize;

        const ctx = scaledCanvas.getContext('2d');

        // 绘制白色背景
        ctx.fillStyle = "white";
        ctx.fillRect(0, 0, canvasSize, canvasSize);

        // 绘制缩放后的图片并居中
        const imageWidth = 300; // 设置二维码图片宽度
        const x = (canvasSize - imageWidth) / 2;
        const y = 50; // 显示在画布中的垂直位置
        ctx.drawImage(canvas, x, y, imageWidth, imageWidth); // 图像居中,从顶部向下50像素处开始

        // 获取编号文字样式
        const numberStyle = window.getComputedStyle(document.querySelector('.qrCode-name'));
        const fontSize = numberStyle.getPropertyValue('font-size');
        const fontColor = numberStyle.getPropertyValue('color');
        const fontWeight = numberStyle.getPropertyValue('font-weight');

        // 将获取到的样式应用到绘制编号的文字上
        ctx.font = `${fontWeight} ${fontSize} Arial`;
        ctx.fillStyle = fontColor;

        // 绘制编号文字
        const text = "设备编号: " + fileName;
        const textX = canvasSize / 2;
        const textY = canvasSize - 20; // 设置位置为画布中心底部,向上偏移20像素
        ctx.textAlign = "center";
        ctx.fillText(text, textX, textY);

        const link = document.createElement("a");
        //文件名
        link.download = fileName + ".png";
        link.href = scaledCanvas.toDataURL("image/png");
        link.click();
      });
    },
相关推荐
OpenTiny社区16 分钟前
Node.js技术原理分析系列——Node.js的perf_hooks模块作用和用法
前端·node.js
菲力蒲LY19 分钟前
输入搜索、分组展示选项、下拉选取,全局跳转页,el-select 实现 —— 后端数据处理代码,抛砖引玉展思路
java·前端·mybatis
飞天大河豚1 小时前
2025前端框架最新组件解析与实战技巧:Vue与React的革新之路
vue.js·react.js·前端框架
MickeyCV2 小时前
Nginx学习笔记:常用命令&端口占用报错解决&Nginx核心配置文件解读
前端·nginx
祈澈菇凉2 小时前
webpack和grunt以及gulp有什么不同?
前端·webpack·gulp
十步杀一人_千里不留行2 小时前
React Native 下拉选择组件首次点击失效问题的深入分析与解决
javascript·react native·react.js
zy0101012 小时前
HTML列表,表格和表单
前端·html
初辰ge2 小时前
【p-camera-h5】 一款开箱即用的H5相机插件,支持拍照、录像、动态水印与样式高度定制化。
前端·相机
HugeYLH2 小时前
解决npm问题:错误的代理设置
前端·npm·node.js
六个点3 小时前
DNS与获取页面白屏时间
前端·面试·dns