记录一次 PDF 文件转 canvas,支持放大/缩小

305 阅读1分钟

参考了网上好几个demo,做个demo笔记

安装pdfjs-dist

npm i pdfjs-dist --save

引用方式

import * as PDFJS from "pdfjs-dist";
import "pdfjs-dist/build/pdf.worker.min.mjs";
  • 关于引用方式,尝试了百度上很多种写法,最后这种引入方式没有报错

html

<template>
  <div>
    <div id="canvas" />
    <footer>
      <el-button @click="hanldeMax">放大</el-button>
      <el-button @click="hanldeMin">缩小</el-button>
    </footer>
  </div>
</template>

<style lang='scss' scope>
footer {
  height: 4rem;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1;
  box-shadow: 0 -0.2rem 0.5rem rgb(50 50 50 / 0.75);
  background: black;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

js

<script lang="ts" setup>
import * as PDFJS from "pdfjs-dist";
import "pdfjs-dist/build/pdf.worker.min.mjs";
const scale = ref(1); // 缩放倍数
//读取pdf文件,并加载到页面中
function loadPDF(fileURL) {
  PDFJS.getDocument(fileURL).promise.then(function (pdf) {
    //用 promise 获取页面
    let id = "";
    const idStr = "cw-pdf-";
    const pageNum = pdf.numPages; //pdf文件总页数
    //根据页码创建画布
    createSeriesCanvas(pageNum, idTemplate);
    //将pdf渲染到画布上去
    for (let i = 1; i <= pageNum; i++) {
      id = idStr + i;
      renderPDF(pdf, i, id);
    }
  });
}
//建议给定pdf宽度
function renderPDF(pdf, i, id) {
  pdf.getPage(i).then(function (page) {
    //  准备用于渲染的 canvas 元素
    const canvas = document.getElementById(id);
    const context = canvas.getContext("2d");
    const dpr = window.devicePixelRatio || 1;
    const bsr =
      context.webkitBackingStorePixelRatio ||
      context.mozBackingStorePixelRatio ||
      context.msBackingStorePixelRatio ||
      context.oBackingStorePixelRatio ||
      context.backingStorePixelRatio ||
      1;
    const ratio = dpr / bsr;
    const viewport = page.getViewport({ scale: scale.value });
    canvas.width = viewport.width * ratio;
    canvas.height = viewport.height * ratio;
    canvas.style.height = viewport.height + "px";
    canvas.style.width = viewport.width + "px";
    context.setTransform(ratio, 0, 0, ratio, 0, 0);
    //
    // 将 PDF 页面渲染到 canvas 上下文中
    //
    const renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    page.render(renderContext);
  });
}
//创建和pdf页数等同的canvas数
function createSeriesCanvas(num, template) {
  let id = "";
  for (let j = 1; j <= num; j++) {
    id = template + j;
    createPdfContainer(id, "pdfClass");
  }
}
//创建canvas元素
function createPdfContainer(id, className) {
  const pdfContainer = document.getElementById("canvas");
  const canvasNew = document.createElement("canvas");
  canvasNew.id = id;
  canvasNew.className = className;
  const div = document.createElement("div");
  const divId = "div-" + id;
  div.id = divId;
  div.className = "dom-wrapper";
  div.appendChild(canvasNew);
  pdfContainer.appendChild(div);
}
const hanldeMax = () => {
  scale.value += 0.1;
  init();
};
const hanldeMin = () => {
  scale.value -= 0.1;
  init();
};

const init = () => {
  //调用
  loadPDF('pdf文件地址');
};
onMounted(() => {
  init();
})
</script>

- over -