vue实现批量导出二维码到PDF(支持分页生成 PDF)

在项目中,我们经常需要将一批二维码(比如库位、设备编号、物料标签等)批量导出成 PDF,方便打印或归档。

本文将介绍如何使用 jsPDF + qrcode 在前端实现这一功能,并支持 自动分页 和 布局控制(4×5 栅格)。

一、安装依赖

javascript 复制代码
# 安装 jsPDF ------ 用于生成和导出 PDF 文件(浏览器端导出)
npm install jspdf

# 安装 qrcode ------ 用于在前端生成二维码(支持生成 Base64 图片)
npm install qrcode

# 安装 html2canvas ------ 用于将页面(DOM)渲染成图片,支持中文和样式
npm install html2canvas

二、引入模块

javascript 复制代码
import QRCode from 'qrcode'
import jsPDF from 'jspdf'
import html2canvas from 'html2canvas'

三、核心实现思路

我们要实现的功能流程如下:

从后端接口获取要导出的数据。前端根据每条数据生成对应的二维码(Base64 图片)。将二维码和名称排版插入到 PDF。当一页二维码放满后,自动分页。导出并保存 PDF 文件。整个过程纯前端实现,无需后端参与,非常方便。

四、完整示例代码

javascript 复制代码
     //处理数据,将字段转成二维码
    async exportLocation() {
      try {
        this.$modal.loading('正在生成二维码,请稍候...')
        const rows = [
          { name: 'A区-01号货位', number: 'LOC-001' },
          { name: 'A区-02号货位', number: 'LOC-002' },
          { name: 'A区-03号货位', number: 'LOC-003' },
          { name: 'B区-01号货位', number: 'LOC-004' },
          { name: 'B区-02号货位', number: 'LOC-005' },
          { name: 'B区-03号货位', number: 'LOC-006' },
          { name: 'C区-01号货位', number: 'LOC-007' },
          { name: 'C区-02号货位', number: 'LOC-008' },
          { name: 'C区-03号货位', number: 'LOC-009' },
          { name: 'D区-01号货位', number: 'LOC-010' }
        ]

        // 并行生成二维码
        const qrList = await Promise.all(
          rows.map(async (item) => {
            const qrCodeUrl = await this.generateQRCode(number)
            return {
              name: item.name || '',
              snCode: qrCodeUrl
            }
          })
        )

        await this.exportPdf(qrList)
        this.$modal.msgSuccess(`导出成功,共 ${qrList.length} 条数据`)
      } catch (err) {
        this.$modal.msgError('导出失败,请稍后重试')
        console.error(err)
      } finally {
        this.$modal.closeLoading()

      }
    },
    // 生成二维码Base64
    async generateQRCode(url) {
      if (!url) return ''
      try {
        return await QRCode.toDataURL(url, {
          errorCorrectionLevel: 'H',
          width: 100,
          margin: 1
        })
      } catch (e) {
        console.error('二维码生成失败:', e)
        return ''
      }
    },
   //导出二维码 PDF(4×5 布局自动分页,支持中文显示,无需字体文件)
  async exportPdf(qrList) {
	 // 创建一个临时的 DOM 容器,用于渲染要导出的内容
	  const container = document.createElement('div')
	  container.style.width = '210mm'               // 设置宽度为 A4 页面宽度
	  container.style.padding = '10mm'              // 设置页面边距
	  container.style.display = 'grid'              // 使用网格布局,方便排列
	  container.style.gridTemplateColumns = 'repeat(4, 1fr)' // 每行 4 列
	  container.style.gridGap = '10px'              // 每个二维码块之间的间距
	  container.style.textAlign = 'center'          // 文本居中
	
	  //  将每个二维码数据添加到容器中
	  qrList.forEach(item => {
	    const div = document.createElement('div')    // 每个二维码块
	    div.style.display = 'flex'
	    div.style.flexDirection = 'column'
	    div.style.alignItems = 'center'
	
	    // 创建二维码图片
	    const img = document.createElement('img')
	    img.src = item.snCode                        // 二维码 Base64 图片
	    img.style.width = '35mm'                     // 设置二维码大小
	    img.style.height = '35mm'
	
	    // 创建二维码下方的中文名称
	    const text = document.createElement('div')
	    text.textContent = item.name                 // ✅ 支持中文
	    text.style.fontSize = '12px'
	    text.style.marginTop = '4px'                 // 图片与文字之间的间距
	
	    // 组合到单个块中
	    div.appendChild(img)
	    div.appendChild(text)
	    container.appendChild(div)
	  })
	
	  // 将生成的容器暂时添加到页面(否则 html2canvas 无法渲染)
	  document.body.appendChild(container)
	
	  // 使用 html2canvas 将 DOM 转为图片
	  const canvas = await html2canvas(container, {
	    scale: 2,       // 提高清晰度(2倍分辨率)
	    useCORS: true   // 允许跨域加载图片(二维码)
	  })
	
	  // 将 canvas 转成 PNG 图片 Base64
	  const imgData = canvas.toDataURL('image/png')
	
	  //  创建 PDF 对象
	  const pdf = new jsPDF('p', 'mm', 'a4')   // 纵向(p),单位毫米(mm),A4 尺寸
	  const imgWidth = 210                     // A4 宽度(mm)
	  const pageHeight = 295                   // A4 高度(mm)
	  const imgHeight = (canvas.height * imgWidth) / canvas.width // 按比例计算图片高度
	
	  //  将图片插入到 PDF 中
	  pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight)
	
	  //  保存 PDF 文件
	  pdf.save('二维码导出.pdf')
	
	  //  清理临时 DOM(不影响页面)
	  document.body.removeChild(container)
}

五、实现效果

相关推荐
Renounce4 小时前
《Android Handler:线程间通信的核心实现》
前端
CAD老兵4 小时前
打造高性能二维图纸渲染引擎系列(一):Batched Geometry 助你轻松渲染百万实体
前端·webgl·three.js
前端老宋Running4 小时前
微信小程序的操作日志收集模块
前端
CAD老兵4 小时前
打造高性能二维图纸渲染引擎系列(三):高性能 CAD 文本渲染背后的隐藏工程
前端·webgl·three.js
不太会写4 小时前
又开始了 小程序定制
vue.js·spring boot·python·小程序
CAD老兵4 小时前
打造高性能二维图纸渲染引擎系列(二):创建结构化和可扩展的渲染场景
前端·webgl·three.js
王木风4 小时前
1分钟理解什么是MySQL的Buffer Pool和LRU 算法?
前端·mysql
Jerry_Rod4 小时前
vue 项目如何使用 mqtt 通信
前端·vue.js
云中雾丽4 小时前
Flutter中路由配置的各种方案
前端