项目需求是把一个pdf转成图片,并在最后添加上二维码,然后下载下来。
经过一番研究以后,作此记录。
主要用到了pdfjs-dist这个包,我用的是2.16.105版本。
废话不多说,直接上代码。
先下载node_modules包
npm i pdfjs-dist -S
然后在vue页面中引入:
import * as pdfjsLib from "pdfjs-dist/legacy/build/pdf.js";
import * as pdfjsWorker from "pdfjs-dist/legacy/build/pdf.worker.entry.js";
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
下面是在methods里面写的方法:
// 通过前台用pdf转图片async pdfForImage(pdf) {this.isExportLoad = true; // 控制加载中const pdfurl = pdf; // 传过来的是pdf的连接console.log(pdfurl, "pdf地址");if (pdfurl) {try {// 读取pdf文件const pdfDoc = await pdfjsLib.getDocument(pdfurl).promise;const pageNum = pdfDoc.numPages;console.log(pageNum, "pdf页数");const promiseArr = [];// 循环pdf每一页for (let i = 1; i <= pageNum; i++) {const page = await pdfDoc.getPage(i);const viewport = page.getViewport({ scale: 1.5 }); // 设置合适的缩放比例// 创建canvas画布const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");canvas.width = viewport.width;canvas.height = viewport.height;// 把每一页Pdf画到canvas中const renderTask = page.render({canvasContext: ctx,viewport: viewport,});// 因为有好多页,所以通过promise完成每一页的canvas画布以后再统一合并图片const promise = new Promise((resolve, reject) => {// 等待渲染完成renderTask.promise.then(() => {resolve({canvas,width: canvas.width,height: canvas.height,});}).catch((error) => {reject({error,canvas: null,width: 0,height: 0,});});});promiseArr.push(promise);}// 等所有pdf页面渲染完成Promise.all(promiseArr).then((res) => {console.log(res, "res");if (res.length > 0) {// 合并canvas并生成图片const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");// 获取最大宽度let width = Math.max(...res.map((item) => item.width));// 获取高度总和let height = res.reduce((total, item) => total + item.height, 0);let num = 0, qrCanvasHeight = 136; // qrCanvasHeight是二维码图片的高度上下预留出20px的间距canvas.width = width;canvas.height = height + qrCanvasHeight; // 高度要加上二维码图片的高度ctx.fillStyle = "#ffffff"; // 给画布加上白色背景,这个色值可以随便更换ctx.fillRect(0, 0, width, height + qrCanvasHeight);res.forEach((item) => {if (item.canvas && item.height > 0) {// 画图片信息ctx.drawImage(item.canvas, 0, num, item.width, item.height);num += item.height;}});// 添加二维码图片const img = new Image();img.src = require("@/assets/qrcode.png"); // 二维码图片地址img.width = 320; // 二维码宽度img.height = 96; // 二维码高度img.onload = () => {ctx.drawImage(img,width / 2 - 160, // 为了让图片左右剧中num + 20, // 让二维码与上方多20px的间距img.width,img.height);// 把canvas生成图片const imageUrl = canvas.toDataURL("image/jpeg", 1); // 我这里是生成为jpg了,也可以传image/png// ctx.scale(2, 2); // 可选:放大图像以便查看(根据需要调整)// console.log(imageUrl, "imageUrl"); // 生成的base64图片地址,可以输出查看// 下载图片const link = document.createElement("a");link.href = imageUrl;link.download = `分析报告.jpg`;document.body.appendChild(link);link.click();document.body.removeChild(link);this.isExportLoad = false;};}});} catch (err) {console.log(err);this.$message.error("pdf文件加载失败");}}},