Ⅰ- 壹 - 功能展示和使用需求
需求描述
前端生成批量二维码,并且下载,本项目使用了 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>