场景一:利用vue向pdf文件中写入二维码图片或其他图片
场景二:向pdf中添加水印
思路:
1、先通过url链接生成二维码,二维码存在于dom中
2、使用html2canvas库将二维码的dom转为一个canvas对象
3、根据canvas对象获取blob中的buffer
4、最后将这个二维码以图片的形式嵌入到pdf文件流中
npm i html2canvas
npm i qrcodejs2-fixes
npm i pdf-lib
import html2canvas from 'html2canvas'
import QRCode from 'qrcodejs2-fixes'
import { degrees, PDFDocument } from 'pdf-lib'
封装qrToPdf.js,用的时候直接调用该方法,将pdf文件流(blob对象)和二维码url链接地址传入进去 就可以,我这里就以window打开一个新页签预览处理之后的pdf为例了,真实项目也可能是下载,都是差不多的,下载也很简单,通过a标签,window.URL.createObjectURL转为一个路径,然后给a标签增加download属性,值为文件名称,click即下载了
src/utils/qrToPdf.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;
// href 就是生成的pdf地址,可以拿到href做不通操作,下载预览等等
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链接
})
vue2大致写法都一样
<template>
<div class="main">
<input id="fileInp" type="file">
</div>
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue'
import previewEmbedQrcodeToPdf from '@/utils/qrToPdf'
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>
此博客主要参考:https://blog.csdn.net/m0_51431448/article/details/131216664
Vue向Pdf添加水印:https://blog.csdn.net/m0_51431448/article/details/129539428?spm=1001.2014.3001.5501