批量生成二维码

一、打开一个生成二维码页面

<template>
<div @click="handleGenerateQrCode ">生成二维码</div>
// 省略表格选中
<QR/ ref="qrRef">
</template>
<script>
const qrRef= ref()
const multipleSelection = ref([])
const handleSelectionChange = (val) => {
  multipleSelection.value = val
  console.log(val)
}


const handleGenerateQrCode = () => {
  // 批量生成二维码
  try {
    qrRef.value.open(multipleSelection)
  } finally {
    qrCodeLoading.value = false
  }
}

二、一个二维码页面

<template>
  <Dialog
    v-model="dialogVisible"
    :title="dialogTitle"
    width="1000px"
    height="1200px"
    @close="handleCloseModal"
  >
    <e-row>
      <el-button type="success" plain v-print="printObj">
        <Icon icon="ep:search" />
        预览打印
      </el-button>
      <el-button type="success" plain @click="handleDownloadClick" :loading="printLoding">
        <Icon icon="ep:download" />
        下载全部
      </el-button>
    </e-row>
    <el-row class="row-con" id="printMe">
      <!--      1-->
      <div
        v-for="(item, index) in tableData"
        :ref="setItemRef"
        :key="item.equCode"
        style="width: 50%"
      >
        <div style="border: dot-dash">
          <div style="width: 100%; display: flex; flex-direction: row">
            <div style="width: 40%">
              <img
                :src="imageData[index]"
                alt="QR Code"
                crossorigin="anonymous"
                style="border-style: none; height: 200px; width: 200px; object-fit: cover"
              />
            </div>
            <div
              style="
                width: 60%;
                display: flex;
                flex-direction: column;
                justify-content: center;
                background-color: white;
              "
            >
              <div class="textMargin">这里可以自定义:{{ item.equCode }}</div>
            </div>
          </div>
        </div>
      </div>
    </el-row>
  </Dialog>
</template>
<script setup lang="ts">
import JSZip from 'JSZip'
import FileSaver from 'file-saver'
import qrcode from 'qrcode'
import html2canvas from 'html2canvas'

const dialogVisible = ref(false)
const dialogTitle = ref('生成二维码')
const printLoding = ref(false)
const handleCloseModal = () => {
  dialogVisible.value = false
}
const tableData = ref([])
const printObj = ref({
  id: 'printMe',
  popTitle: '',
  extraCss:
    'https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css',
  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
  beforeOpenCallback(vue) {
    vue.printLoading = true
    console.log('打开之前')
  },
  openCallback(vue) {
    vue.printLoading = false
    console.log('执行了打印', vue)
  },
  closeCallback(vue) {
    console.log('关闭了打印工具', vue)
  }
})

const itemRefs = ref([])
const setItemRef = (el) => {
  if (el) {
    itemRefs.value.push(el)
  }
}
const handleCanvas = ref([]) as any
const imageData = ref([]) as any
const open = (data) => {
  dialogVisible.value = true
  console.log('data', data)
  tableData.value = data.value
  console.log('tableData', tableData.value)
  imageData.value = []
  tableData.value.forEach((item) => {
    //var code = 'your-data' // 替换为你需要生成二维码的数据
    qrcode.toDataURL(item.equCode, (err, url) => {
      if (err) {
        console.error(err)
      } else {
        console.log('toDataURL', url)
        imageData.value.push(url)
      }
    })
  })
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
const handleDownloadClick = () => {
  printLoding.value = true
  handleCanvas.value = []
  itemRefs.value.forEach((item, index) => {
    html2canvas(itemRefs.value[index], {
      backgroundColor: '#f5f5f9',
      useCORS: true, // 解决文件跨域问题
      scrollY: 0,
      scrollX: 0
    })
      .then((canvas) => {
        var dataURL = canvas.toDataURL('image/png')

        console.log('tableData', index, tableData)
        handleCanvas.value.push({
          fileUrl: dataURL,
          renameFileName: tableData.value[index]['equCode'] + '.png'
        })
        console.log('handleCanvas.value.', handleCanvas.value)

        if (handleCanvas.value.length == tableData.value.length) {
          filesToRar()
        }
        // t.handleCanvas.push({
        //   fileUrl: dataURL,
        //   renameFileName: '准考证' + index + '.png'
        // })
        //注意 文件名不可重复 如果重复zip包里只会有一张图片
        // if(生成图片结束后的判断){
        //   this.filesToRar()
        // }
      })
      .catch((err) => {
        console.log(err)
      })
      .finally(() => {
        printLoding.value = false
      })
  })
}
const filesToRar = () => {
  console.log('filesToRar')
  let zip = new JSZip()
  let cache = {}
  let promises = []
  for (let item of handleCanvas.value) {
    const promise = getImage(item.fileUrl).then((data) => {
      // 下载文件, 并存成ArrayBuffer对象(blob)
      zip.file(item.renameFileName, data, {
        binary: true
      }) // 逐个添加文件
      // zip.file(item.renameFileName, data, {base64: true}); // 逐个添加文件
      cache[item.renameFileName] = data
    })
    promises.push(promise)
  }
  console.log('Promise')
  Promise.all(promises)
    .then(() => {
      zip
        .generateAsync({
          type: 'blob'
        })
        .then((content) => {
          console.log('Promise.then')
          const date = new Date()
          // 生成二进制流
          FileSaver.saveAs(content, date.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })) // 利用file-saver保存文件  自定义文件名
        })
    })
    .catch((res) => {
      console.log('Promisecatch', res)
      // _this.$message.error('文件压缩失败')
    })
}
获取文件blob
const getImage = (url) => {
  return new Promise((resolve, reject) => {
    //通过请求获取文件blob格式
    let xmlhttp = new XMLHttpRequest()
    xmlhttp.open('GET', url, true)
    xmlhttp.responseType = 'blob'
    xmlhttp.onload = function () {
      if (this.status == 200) {
        resolve(this.response)
      } else {
        reject(this.status)
      }
    }
    xmlhttp.send()
  })
}
</script>
<style scoped lang="scss">
.row-con {
  display: flex;
  flex-flow: row wrap;
}

.row-con .card {
  height: 100%;
}

.textMargin {
  //margin: 3% 2%;
  margin-bottom: 3%;
  font-size: 20px;
  font-weight: bold;
  color: black;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值