vue3 渲染pdf并下载

359 阅读1分钟

下载pdfjs-dist

npm install pdfjs-dist

引入包并定义canvas

<template>
  <div id="pdf">
    <canvas id="the-canvas" ref="renderContext"></canvas>
  </div>
</template>

<script lang="ts" setup>
import * as PDFJS from "pdfjs-dist/legacy/build/pdf"; // 引入PDFJS
import pdfjsWorker from "pdfjs-dist/legacy/build/pdf.worker.entry.js"; // 引入workerSrc的地址

import { ref, getCurrentInstance } from "vue";

PDFJS.GlobalWorkerOptions.workerSrc = pdfjsWorker; //设置PDFJS.GlobalWorkerOptions.workerSrc的地址

得到pdfbase数据并渲染

const printpdf = ref("pdf的base64数据")

let renderContext = ref(null);
let pdfPagesNum = ref(0);
let readerpdfDoc = null;

const pdfData = atob(printpdf.value)

function showPdf(pdfDoc, pageNum) {
  pdfDoc.getPage(pageNum).then((page) => {
    // 设置canvas相关的属性
    const canvas = renderContext.value;
    const ctx = canvas.getContext("2d");
    const dpr = window.devicePixelRatio || 1;
    const bsr =
      ctx.webkitBackingStorePixelRatio ||
      ctx.mozBackingStorePixelRatio ||
      ctx.msBackingStorePixelRatio ||
      ctx.oBackingStorePixelRatio ||
      ctx.backingStorePixelRatio ||
      1;
    const ratio = dpr / bsr;
    const viewport = page.getViewport({ scale: 1 });
    canvas.width = viewport.width * ratio;
    canvas.height = viewport.height * ratio;
    canvas.style.width = viewport.width + "px";
    canvas.style.height = viewport.height + "px";
    ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
    const context = {
      canvasContext: ctx,
      viewport: viewport,
    };
    // 数据渲染到canvas画布上
    const renderTask = page.render(context);

    console.log('renderTask', renderTask)

    renderTask.promise.then(function () {
        console.log('Page rendered');
    });
  });
}

const getPdf = () => {
  PDFJS.getDocument({ data: pdfData }).promise.then((pdfDoc) => {
   
    pdfPagesNum.value = pdfDoc.numPages * 10; // pdf的总页数
    //获取第pageNum页的数据
    readerpdfDoc = pdfDoc;

    showPdf(pdfDoc,1)
  })
}

getPdf()

把base64数据转成二进制并下载

// 将base64转为二进制Unicode编码
const base64toBlob = (bstr) => {
    let n = bstr.length, 
    u8arr = new Uint8Array(n); // 新建一个8位的整数类型数组,用来存放ASCII编码的字符串
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n) // 转换编码后才使用charCodeAt 找到Unicode编码 
    }
    return u8arr
}

const blobFn = () => {

      let blob = new Blob([base64toBlob(pdfData)], {
        type: "application/pdf",
      });
      const fileName = '测试' + '.pdf' // 下载文件名称
      const elink = document.createElement('a')
      elink.download = fileName
      elink.style.display = 'none'
      elink.href = URL.createObjectURL(blob)
      document.body.appendChild(elink)
      elink.click()
      URL.revokeObjectURL(elink.href) // 释放URL 对象
      document.body.removeChild(elink)
}

blobFn()