Vue實(shí)現(xiàn)向PDF文件中添加二維碼
前言
這兩天剛看到一個(gè)需求,簡單描述一下,就是我們拿到一個(gè)pdf文件流(文件流可以是后端返回的,也可以是從自己本地選的)和一個(gè)url鏈接 ,現(xiàn)在要將url鏈接生成二維碼,并將這個(gè)二維碼添加到這個(gè)pdf文件中,然后再預(yù)覽或者下載這個(gè)pdf文件。
靈感出自于我之前寫過一篇Vue使用pdf-lib為文件流添加水印并預(yù)覽,上篇寫的是在pdf上加水印,其中一種方式就是通過圖片的方式添加上去的,所以這次添加二維碼基本差不多一個(gè)意思,我們可以先通過url鏈接生成一個(gè)二維碼,這個(gè)二維碼其實(shí)是個(gè)dom元素的,我們使用html2canvas庫可以將二維碼這個(gè)dom轉(zhuǎn)為一個(gè)canvas對象,有了canvas是不是可以獲取到Blob對象了?有了blob就可以獲取到buffer了,那我們就可以將這個(gè)二維碼以圖片的形式嵌入到pdf文件流中。
共用到三個(gè)庫分別是:html2canvas 、qrcodejs2-fixes、pdf-lib。
注意這里生成二維碼共有兩個(gè)庫,一個(gè)是qrcodejs2,這個(gè)由于兼容性問題只支持vue2,我這里的例子是用vue3來演示的,所以就是用第二個(gè):qrcodejs2-fixes,這個(gè)使用跟qrcodejs2一樣,區(qū)別就是一個(gè)適用vue2一個(gè)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'
封裝
這里單獨(dú)封裝一個(gè)方法,用的時(shí)候直接調(diào)用該方法,將pdf文件流(blob對象)和二維碼url鏈接地址傳入進(jìn)去 就可以,我這里就以window打開一個(gè)新頁簽預(yù)覽處理之后的pdf為例了,真實(shí)項(xiàng)目也可能是下載,都是差不多的,下載也很簡單,通過a標(biāo)簽,window.URL.createObjectURL轉(zhuǎn)為一個(gè)路徑,然后給a標(biāo)簽增加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, // 距離右側(cè)100 y: height - 100, // 距離上側(cè)100 就是右上角 width: dims.width, height: dims.height, rotate: degrees(0) }) } const pdfBytes = await pdfDoc.save() preView(pdfBytes) document.body.removeChild(qrcodeDom) }) }, 'image/png') }) }) } // 打開新頁簽預(yù)覽 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) // 設(shè)置新打開的頁簽 document title let timer = setInterval(() => { if (wo.closed) { clearInterval(timer) } else { wo.document.title = docTitle } }, 500) }
封裝的方法中的二維碼樣式啥的,我也懶得動(dòng)態(tài)設(shè)置參數(shù)傳入了,大家有需要在封裝的方法中按需修改即可
引入調(diào)用使用的時(shí)候:
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效果
右上角這個(gè)二維碼就是我們生成的,添加到這個(gè)pdf中的,我這里是以baidu的鏈接為例的,所以掃出來也是百度的鏈接
到此這篇關(guān)于Vue實(shí)現(xiàn)向PDF文件中添加二維碼的文章就介紹到這了,更多相關(guān)Vue PDF添加二維碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue實(shí)現(xiàn)彈出框點(diǎn)擊空白頁彈框消失效果
這篇文章主要介紹了VUE實(shí)現(xiàn)彈出框點(diǎn)擊空白頁彈框消失,實(shí)現(xiàn)方法可以在Vue中實(shí)現(xiàn)彈出框然后通過點(diǎn)擊空白頁面來讓彈窗隱藏,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12Vue實(shí)現(xiàn)關(guān)聯(lián)頁面多級跳轉(zhuǎn)(頁面下鉆)功能的完整實(shí)例
這篇文章主要給大家介紹了關(guān)于Vue實(shí)現(xiàn)關(guān)聯(lián)頁面多級跳轉(zhuǎn)(頁面下鉆)功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03vue刷新子組件、重置組件以及重新加載子組件項(xiàng)目實(shí)戰(zhàn)記錄
在vue開發(fā)中出于各種目的,我們常常需要讓組件重新加載渲染,這篇文章主要給大家介紹了關(guān)于vue刷新子組件、重置組件以及重新加載子組件的相關(guān)資料,需要的朋友可以參考下2023-12-12解決VUE中document.body.scrollTop為0的問題
今天小編就為大家分享一篇解決VUE中document.body.scrollTop為0的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue實(shí)現(xiàn)仿淘寶結(jié)賬頁面實(shí)例代碼
本文是小編給大家分享的vue實(shí)現(xiàn)仿淘寶結(jié)賬頁面實(shí)例代碼,主要功能是仿照淘寶頁面的結(jié)算購物車商品時(shí)自動(dòng)算出合計(jì)價(jià)格的頁面,具體實(shí)例代碼大家參考下本文2017-11-11Vue中實(shí)現(xiàn)動(dòng)畫效果的多種方法小結(jié)
平時(shí)我們能在網(wǎng)頁上看到很多動(dòng)畫效果,這些效果看起來就很引人注目,我們是不是也可以在自己的項(xiàng)目中添加一些動(dòng)畫效果,讓我們的頁面看起來更加的高端大氣上檔次,博人眼球,所以本文給大家介紹了Vue中實(shí)現(xiàn)動(dòng)畫效果的多種方法,需要的朋友可以參考下2024-07-07element?table?表格控件實(shí)現(xiàn)單選功能
本文主要介紹了element?table?表格控件實(shí)現(xiàn)單選功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07