Vue实现向PDF文件中添加二维码
作者:会说法语的猪
前言
这两天刚看到一个需求,简单描述一下,就是我们拿到一个pdf文件流(文件流可以是后端返回的,也可以是从自己本地选的)和一个url链接 ,现在要将url链接生成二维码,并将这个二维码添加到这个pdf文件中,然后再预览或者下载这个pdf文件。
灵感出自于我之前写过一篇Vue使用pdf-lib为文件流添加水印并预览,上篇写的是在pdf上加水印,其中一种方式就是通过图片的方式添加上去的,所以这次添加二维码基本差不多一个意思,我们可以先通过url链接生成一个二维码,这个二维码其实是个dom元素的,我们使用html2canvas库可以将二维码这个dom转为一个canvas对象,有了canvas是不是可以获取到Blob对象了?有了blob就可以获取到buffer了,那我们就可以将这个二维码以图片的形式嵌入到pdf文件流中。
共用到三个库分别是:html2canvas 、qrcodejs2-fixes、pdf-lib。
注意这里生成二维码共有两个库,一个是qrcodejs2,这个由于兼容性问题只支持vue2,我这里的例子是用vue3来演示的,所以就是用第二个:qrcodejs2-fixes,这个使用跟qrcodejs2一样,区别就是一个适用vue2一个vue3
安装
pnpm add html2canvas pnpm add qrcodejs2-fixes pnpm add pdf-lib
引入
import html2canvas from 'html2canvas' import QRCode from 'qrcodejs2-fixes' import { degrees, PDFDocument } from 'pdf-lib'
封装
这里单独封装一个方法,用的时候直接调用该方法,将pdf文件流(blob对象)和二维码url链接地址传入进去 就可以,我这里就以window打开一个新页签预览处理之后的pdf为例了,真实项目也可能是下载,都是差不多的,下载也很简单,通过a标签,window.URL.createObjectURL转为一个路径,然后给a标签增加download属性,值为文件名称,click即下载了。这里就没以下载为例
src/hooks/EmbedQrcodeToPdf.js
import html2canvas from 'html2canvas' import QRCode from 'qrcodejs2-fixes' import { degrees, PDFDocument } from 'pdf-lib' export default function ({ pdfBlob, qrcodeUrl = 'https://www.baidu.com/' }) { if(!pdfBlob) return pdfBlob.arrayBuffer().then(async buffer => { const pdfDoc = await PDFDocument.load(buffer) const qrcodeDom = document.createElement('div') qrcodeDom.id = 'wft-qrcode' document.body.appendChild(qrcodeDom) new QRCode(document.getElementById('wft-qrcode'), { text: qrcodeUrl, width: '128', height: '128', colorDark: '#000000', colorLight: '#ffffff', correctLevel: QRCode.CorrectLevel.H, }) html2canvas(document.getElementById('wft-qrcode')).then(canvas => { canvas.toBlob(qrcodeBlob => { qrcodeBlob.arrayBuffer().then(async qrcodeBuffer => { const image = await pdfDoc.embedPng(qrcodeBuffer) const dims = image.scale(0.6) const pages = pdfDoc.getPages() for (let i = 0; i < pages.length; i++) { let page = pages[i] const { width, height } = page.getSize() page.drawImage(image, { x: width - 100, // 距离右侧100 y: height - 100, // 距离上侧100 就是右上角 width: dims.width, height: dims.height, rotate: degrees(0) }) } const pdfBytes = await pdfDoc.save() preView(pdfBytes) document.body.removeChild(qrcodeDom) }) }, 'image/png') }) }) } // 打开新页签预览 function preView(stream, docTitle = '测试PDF') { const URL = window.URL || window.webkitURL; const href = URL.createObjectURL(new Blob([stream], { type: 'application/pdf;charset=utf-8' })) const wo = window.open(href) // 设置新打开的页签 document title let timer = setInterval(() => { if (wo.closed) { clearInterval(timer) } else { wo.document.title = docTitle } }, 500) }
封装的方法中的二维码样式啥的,我也懒得动态设置参数传入了,大家有需要在封装的方法中按需修改即可
引入调用使用的时候:
previewEmbedQrcodeToPdf({ pdfBlob: file, // 你的文件流 qrcodeUrl: 'xxxx' // 你的生成二维码的url链接 })
使用案例代码(V3)
<template> <div class="main"> <input id="fileInp" type="file"> </div> </template> <script setup> import { onMounted, onUnmounted } from 'vue' import previewEmbedQrcodeToPdf from '../hooks/EmbedQrcodeToPdf' let cusInp = null onMounted(() => { cusInp = document.getElementById('fileInp') cusInp.addEventListener('input', inpHander) }) onUnmounted(() => { cusInp.removeEventListener('input', inpHander) }) function inpHander(event) { const file = event.target.files[0] if(!file) return previewEmbedQrcodeToPdf({ pdfBlob: file }) } </script> <style scoped> .main { width: 100%; height: 100%; } </style>
demo效果
右上角这个二维码就是我们生成的,添加到这个pdf中的,我这里是以baidu的链接为例的,所以扫出来也是百度的链接
到此这篇关于Vue实现向PDF文件中添加二维码的文章就介绍到这了,更多相关Vue PDF添加二维码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!