当前位置: 首页 > article >正文

vue项目纯前端把PDF转成图片并下载

项目需求是把一个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文件加载失败");
        }
      }
    },


http://www.kler.cn/a/580133.html

相关文章:

  • [250310] Mistral 发布世界领先的文档理解 API:Mistral OCR | 谷歌利用 AI 保护自然的三种新方式
  • 三星首款三折叠手机被曝外屏6.49英寸:折叠屏领域的新突破
  • DOM容器
  • 刷题记录(LeetCode 78 子集)
  • preact组件案例的使用
  • 常见HTTP 状态码及意义
  • Vue脚手架基础
  • 【Servlet】深入解析 Servlet 启动过程 —— 原理分析、代码实战及在 JDK 和 Spring 中的应用
  • Unity ES3保存类的问题
  • 单元测试、系统测试和集成测试知识总结
  • javaEE初阶————多线程进阶(2)
  • 信息安全访问控制、抗攻击技术、安全体系和评估(高软42)
  • RabbitMQ配置消息转换器
  • 【Linux】初识线程
  • 面试:hive的优化, 4个by, 存储过程和自定义函数
  • 【Java学习】泛型
  • 谷歌AI最新发布的可微分逻辑元胞自动机(DiffLogic CA)
  • lnmp平台
  • React 学习全阶段总结
  • 基于Kubernetes部署MySQL主从集群