记录vite5.4+vue3.4使用pdfjs的使用方法

278 阅读2分钟

前言

pdfjs这个库还是比较强大的,除了一些常用的pdf处理功能还提供比如将pdf图像渲染到canvas的功能,在做一些关于pdf用户交互处理方面还是很好用的,无奈官方文档对于目前主流框架如何使用写的不是特别完备,特此记录。

安装

一、使用node或者yarn

使用node
npm i pdfjs-dist
使用yarn
yarn add pdfjs-dist
如果需要ts支持,则需要安装
pnpm安装应该类似吧(没太用过pnpm)

二、在项目中引入

一般使用都需要全局引入

import * as pdfjsLib from "pdfjs-dist"

下面这个比较关键,需要设置包提供的工作线程的js文件路径,具体实现与你使用的框架有关,比如我使用的是vite,在引入静态资源时就可以参考vite提供的方式,不了解的可以参见vite如何引入静态资源,如果设置错误的话,在使用过程中会在控制台看到一个警告,大意就是使用了虚假线程之类的。

pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
  "pdfjs-dist/legacy/build/pdf.worker.min.mjs",
  import.meta.url
).toString();

三、使用举例

我的项目的一个小需求就是拿到用户上传pdf的页面,然后渲染到canvas画布里面,供用户进行后续的一些操作(比如拖拽排序之类的),那么我们就可以参考pdfjs官网的实例和API来完成上述工作,示例代码如下

export const getPdfPages = async (
  pdfFileList: File[],
  config = { scale: 0.23, width: 120, height: 160 }
) => {
  const outputScale = window.devicePixelRatio || 1;
  const imageUrlList: string[] = [];
  for (const [index, file] of Object.entries(pdfFileList)) {
    const pdfUrl = URL.createObjectURL(file);
    const loadingTask = pdfjsLib.getDocument(pdfUrl);
    const pdf = await loadingTask.promise;
    const page = await pdf.getPage(1);
    const pdfViewPort = page.getViewport({
      scale: config.scale,
    });
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d")!;
    canvas.width = Math.floor(pdfViewPort.width * outputScale);
    canvas.height = Math.floor(pdfViewPort.height * outputScale);
    canvas.style.width = Math.floor(pdfViewPort.width) + "px";
    canvas.style.height = Math.floor(pdfViewPort.height) + "px";
    const transform =
      outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;

    const renderContext = {
      canvasContext: ctx,
      viewport: pdfViewPort,
      transform: transform!,
    };

    await page.render(renderContext).promise;
    const imageDataUrl = canvas.toDataURL();
    imageUrlList.push(imageDataUrl);
  }
  return imageUrlList;
};

基本上引入+线程设置就这些,如果你使用的是其他构建工具或者其他框架,可以参考具体的静态资源导入实现。