前端生成批量二维码,并且下载到本地

news2024/11/24 9:50:52

Ⅰ- 壹 - 功能展示和使用需求

需求描述

前端生成批量二维码,并且下载,本项目使用了 vue3.

功能展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Ⅱ - 贰 - 封装代码

需要的库

yanr add qrcodejs2-fix // 生成二维码
yarn add html2canvas // 转图片
yarn add jszip// 压缩包
yarn add file-saver// 下载

index.scss

#HomePage {
    height: 100vh;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    position: relative;

    .tabs-box {
        width: 90%;
        height: 90vh;
        margin-bottom: 15px;
    }
    .qrcode-pic{
        position: absolute;
        bottom: 100px;
        display: flex;
        // display: none;
    }
}

index.vue

<!--
    * @Author: whq
    * @Date: 2022-12-28 11:28:13
 * @LastEditTime: 2023-07-24 16:03:10
 * @LastEditors: whq
    * @Description: 
 * @FilePath: \newEraUniform\src\view\HomePage\index.vue
   -->
<template>
    <div id="HomePage">
        <div class="tabs-query"></div>
        <el-button size="small" @click="handleClick('QRcode')">下载二维码</el-button>
        <div class="tabs-box">
            <el-table ref="multipleTableRef" :data="state.dataList" style="width: 100%"
                @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="55" />
                <el-table-column label="时间" width="120">
                    <template #default="scope">{{ scope.row.date }}</template>
                </el-table-column>

                <el-table-column property="name" label="名称" width="120" />
                <el-table-column property="address" label="电话号码" show-overflow-tooltip />
            </el-table>
        </div>

        <el-pagination v-model:currentPage="state.pages.currentPage" :page-sizes="[20, 30, 50, 100]"
            :page-size="state.pages.size" layout=" prev, pager, next, jumper,total, sizes," :background="true"
            :total="state.pages.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
        <div class="qrcode-pic">
            <div v-for="(v, i) in state.multipleSelection" :key="i">
                <div ref="codeItem"></div>
            </div>
        </div>
        <div v-for="(v, i) in state.QRcodeArr" :key="i">
            <el-image style="width: 100px; height: 100px" :src="v.imgurl" fit="fill" />
        </div>
        <!-- 必须存在的dom 生成的二维码通过这种方式隐藏 -->
        <div id="qrid" :style="{ 'margin-top': '-99999999999999999px', position: 'fixed' }"></div>
    </div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive, watch } from 'vue'
import QRcode from "qrcodejs2-fix";
import html2canvas from 'html2canvas'
import JSZip from "jszip"
import FileSaver from 'file-saver';
import { ElMessage } from 'element-plus';
const codeItem = ref<any>(null)

const state = reactive<any>({
    QRcodeArr: [],
    dataList: [
        {
            id: "1001",
            date: '2016-05-03',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1002",
            date: '2016-05-02',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1003",
            date: '2016-05-01',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1004",
            date: '2016-05-08',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1005",
            date: '2016-05-06',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1006",
            date: '2016-05-07',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1007",
            date: '2016-05-03',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1008",
            date: '2016-05-02',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1009",
            date: '2016-05-04',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1010",
            date: '2016-05-01',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1011",
            date: '2016-05-08',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1012",
            date: '2016-05-06',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            id: "1013",
            date: '2016-05-07',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
    ],
    multipleSelection: [],
    pages: {
        total: 500,//总数据
        currentPage: 1,// 当前页数
        size: 20,// 一页显示多少条
    }
})
const handleSelectionChange = (val: any) => {
    state.multipleSelection = val
    console.log(val);

}
const handleSizeChange = (val: number) => {
    console.log(`${val} items per page`)
}
const handleCurrentChange = (val: number) => {
    console.log(`current page: ${val}`)
}

//  生成二维码图片
const setQRcodeArr = async () => {
    let qridElement: any = document.querySelector('#qrid')
    qridElement.innerHTML = ''
    for (const itemIterator of state.multipleSelection) {
        let newDivElement: any = document.createElement("div")
        newDivElement.innerHTML = "";

        var qrcode = new QRcode(newDivElement, {
            text: 'https://www.baidu.com/', //二维码内容
            width: 120,
            height: 120,
            render: 'table',
            colorDark: "#333333", //二维码颜色
            colorLight: "#ffffff", //二维码背景色
            correctLevel: QRcode.CorrectLevel.H
        })
        qridElement.appendChild(newDivElement)

        // 创建画布放二维码,方便下载
        let canvas: any = document.createElement("canvas"),
            scale = 1;
        canvas.width = 120;
        canvas.height = 120;
        canvas.getContext("2d").scale(scale, scale);
        let opts = {
            canvas: canvas,
            logging: false,
            width: 120,
            height: 120,
            useCORS: true,
            allowTaint: true,//允许跨域图片
            scale: 1, // 处理模糊问题
            dpi: 300, // 处理模糊问题
            background: "#ffffff",
        }
        // 生成二维码图片
        await html2canvas(newDivElement, opts).then((canvas) => {
            const qrContentImage = canvas.toDataURL('image/png', 1.0);// 生成的图片
            state.QRcodeArr.push({
                ...itemIterator,
                imgurl: qrContentImage
            })

        }).catch(function (reason) {
            console.log(reason);
        });
        //下载文件

    }
    qridElement.innerHTML = ''
    //创建压缩对象
    var zip = new JSZip();

    for (const QRcodeIterator of state.QRcodeArr) {
        zip.file(`${QRcodeIterator.id}.png`, QRcodeIterator.imgurl.replace(/^data:image\/(png|jpg);base64,/, ""), { base64: true }); //第一个参数是图片名字和后缀
    }

    //下载压缩包
    zip.generateAsync({ type: "blob" }).then(function (content: any) {
        FileSaver(content, "二维码.zip");
    });
}

const handleClick = async (type: any) => {

    switch (type) {
        case 'QRcode':

            if (!state.multipleSelection.length) {
                return ElMessage({
                    message: '请选择要下载的信息',
                    type: 'warning',
                })
            }
            await setQRcodeArr()


            break;

        default:
            break;
    }

}

onMounted(() => {

})

</script>
<style lang="scss" scoped>
@import "./index.scss";
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/785626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

25.2 matlab里面的10中优化方法介绍——插值法(matlab程序)

1.简述 插值法 插值法又称“内插法”&#xff0c;是利用函数f (x)在某区间中已知的若干点的函数值&#xff0c;作出适当的特定函数&#xff0c;在区间的其他点上用这特定函数的值作为函数f (x)的近似值&#xff0c;这种方法称为插值法。如果这特定函数是多项式&#xff0c;就称…

(css)列表点击前后样式

(css)列表点击前后样式 效果&#xff1a; html <ul v-show"rightOne" class"one-content"><liv-for"(item,index) in exampleList":key"index"click"searchHandle(item,index)"class"liClass":class&qu…

Linux基本指令操作

登陆指令&#xff08;云服务器版&#xff09; 当我们获取公网IP地址后&#xff0c;我们就可以打开xshell。 此时会有这样的界面&#xff0c;我们若是想的登陆&#xff0c;则需要输入以下的指令 ssh 用户名公网IP地址 然后会跳出以下的窗口 接着输入密码——密码便是先前定好…

ArcGIS Engine 与 Visual Studio版本对照表

通过C#对于Arcgis的二次开发&#xff0c;需要Visual Studio版本需要与ArcGIS Engine对应&#xff0c;Visual Studio版本的或高或低都不能使ArcObjects SDK for microsoft.Net framework安装成功。下面是各个版本的对照表。 序号ArcEngine版本visual Studio版本Network版本110.…

React Native实现理想的震动效果

React Native实现理想的震动效果 一、背景说明 业务开发中&#xff0c;总会用到一些和用户反馈的效果&#xff0c;用来提升用户对于某个事件或者操作的重要程度&#xff0c;比如常见的就是 长按复制、滑动或点击图表、点击底部TabBar时的反馈等操作。 二、构思实现及过程 2.…

微信小游戏个人开发者上架:从注册到上线的详细步骤

微信小游戏个人开发者上架&#xff1a;从注册到上线的详细步骤 一&#xff0c;注册小程序账号1.1 微信公众平台1.2 填写信息1.3 绑定管理 二&#xff0c;打包步骤2.1 工具准备2.2 关于Unity版本2.3 打包详解 三&#xff0c;提包步骤3.1 填写用户隐私3.2 完善开发者自查3.3 游戏…

《向量数据库指南》:向量数据库Pinecone使用命名空间

目录 创建命名空间 创建多个命名空间 跨所有命名空间的操作 Pinecone允许您将索引中的向量划分为命名空间。然后,查询和其他操作仅限于一个命名空间,因此不同的请求可以搜索索引的不同子集。 例如,您可能想为按内容索引的文章定义一个命名空间,为按标题索引的文章定义另…

内存条的故障修复方法分享

你知道电脑的内存条遇到故障要怎么修复吗&#xff1f;可能很多小伙伴都是直接说&#xff1a;“找电脑维修师傅就好。”那当只有你自己的时候怎么办呢&#xff1f;今天我就跟你分享几个电脑常见的故障以及修复的方法吧。 1、开机无显示。此类故障通常是由于内存条与主板内存插槽…

kernel-pwn之ret2dir利用技巧

前言 ret2dir是2014年在USENIX发表的一篇论文&#xff0c;该论文提出针对ret2usr提出的SMEP、SMAP等保护的绕过。全称为return-to-direct-mapped memory&#xff0c;返回直接映射的内存。论文地址&#xff1a;https://www.usenix.org/system/files/conference/usenixsecurity1…

如何在电脑上查看连接过的wifi信息?

忘记wifi密码&#xff1f;想要看看wifi信息&#xff1f; 我想这篇文章可以帮到你O(∩_∩)O哈哈~。 通过网络连接中心查看 电脑上找到“网络和共享中心” 点击连接的wifi名称 点击无线属性 在安全选项中就有密码 通过电脑命令行工具查看推荐 通过winr快捷键打开电脑运…

vue echarts实现月度年度可切换,自适应的柱状统计图功能

echarts配置文档参考&#xff1a;Documentation - Apache ECharts 功能&#xff1a;可进行月度、年度切换显示相应的收入和支出柱状图数据&#xff1b; 这里进行了柱状图的简化配置&#xff0c;X轴Y轴都有所改写&#xff0c;具体的简化配置下文会贴出代码&#xff0c;参照功能开…

LiveGBS流媒体平台GB/T28181功能-支持轮巡播放分屏轮巡值守播放监控视频轮播大屏轮询播放

LiveGBS支持轮巡播放分屏轮巡值守播放监控视频轮播大屏轮询播放 1、背景2、分屏展示3、选择轮播通道4、配置轮播间隔(秒)5、点击开始轮播6、轮播停止及全屏7、搭建GB28181视频直播平台 1、背景 视频监控项目使用过程中&#xff0c;有时需要大屏值守&#xff0c;值守的时候多分…

(学习笔记-IP)Ping的工作原理

Ping是基于ICMP协议工作的&#xff0c;ICMP报文封装在IP包里面&#xff0c;它工作在网络层&#xff0c;是IP协议的助手。 ICMP包头的类型字段&#xff0c;大致可分为两大类&#xff1a; 一类是用于诊断的查询消息&#xff0c;也就是查询报文类型一类是通知出错原因的错误消息&…

PDF添加水印以及防止被删除、防止编辑与打印

方法记录如下&#xff1a; 1、添加水印&#xff1b; 2、打印输出成一个新的pdf&#xff1b; 3、将pdf页面输出成一张张的图片&#xff1a;&#xff08;福昕pdf操作步骤如下&#xff09; 4、将图片组装成一个新的pdf&#xff1a;&#xff08;福昕pdf操作步骤如下&#xff09;…

C# 使用opencv从图片识别人脸示例

1.用chatgpt帮我写了一个示例 using System; using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Structure;class Program {static void Main(string[] args){// 加载人脸分类器CascadeClassifier faceCascade new CascadeClassifier("haarcascade_frontalface_defau…

Kafka基础架构与核心概念

Kafka简介 Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。架构特点是分区、多副本、多生产者、多订阅者&#xff0c;性能特点主要是…

测试人必看:五大维度解读软件测试分类

软件测试方法种类繁多&#xff0c;记忆起来也非常混乱&#xff0c; 如果把软件测试方法进行多个维度的分类, 就会清晰很多。 软件测试的分类-按开发阶段分类 单元测试 又称模块测试&#xff0c;针对软件设计中的最小单位-程序模块&#xff0c;进行正确性检查的测试工作。单元…

谷粒商城第五天-将项目改为基于若依框架实现、使用若依进行代码生成(生成MyBatisPlus风格)

目录 一、使用若依框架来搭建后台管理系统 1.1 前端部分 1.2 后端部分 1.2.1 将若依框架植入到项目中 1.2.2 完成数据库配置 二、使用若依框架的逆向生成工具逆向生成代码&#xff08;同时将代码风格改为MyBatisPlus&#xff09; 2.1 使用若依框架提供的逆向生成工具生成…

思科路由器交换机密码破解教程

1. 路由器密码的恢复. 2600、3600等新系列路由器步骤&#xff1a; 1、启动路由器&#xff0c;60秒内按下ctrlbreak键2、rommon>confreg 0x21423、rommon>reset4、router#copy startup-config running-config5、router(config)#no enable secrect //可以删除密码也可以更…

linux升级mysql

linux升级mysql 一.介绍二.下载三.文件配置1.查找删除mysql2.解压配置 四.修改配置五.初始化mysql服务六.启动mysql七.配置数据库七.测试 一.介绍 由于最近业务需要&#xff0c;不得不将之前的mysql5.7.26升级到mysql8.0加了 Linux安装mysql&#xff08;5.7.26&#xff09;&…