vue3 带密钥预览pdf

275 阅读1分钟

干货,已实践好用
首先使用npm安装pdfjs-dist库,用的最新版"pdfjs-dist": "^4.7.76"

npm install pdfjs-dist
<div id="pdf-canvas-container" class="canvas-container"></div>
<script lang="ts" setup>
//@ts-ignore
import * as pdfjsLib from 'pdfjs-dist/build/pdf';
import 'pdfjs-dist/build/pdf.worker.mjs';

let pdfUrl = ""; //你的pdf URL地址 
let decryptionKey = ""; //你的密钥
let pdfDoc:any = null;
let scale:number = 1;
async function loadAndRenderPDF() {
  try {
    // pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js';
    // 加载PDF文档
    const loadingTask = pdfjsLib.getDocument({ url: pdfUrl, password: decryptionKey });
    pdfDoc = await loadingTask.promise;
    renderAllPages();
  } catch (error) {
    console.error('解密失败: ', error);
  }
}
//渲染所有页面
async function renderAllPages() {
  clearCanvases();
  const pages = pdfDoc.numPages;
  for (let pageNum = 1; pageNum <= pages; pageNum++) {
    renderPage(pageNum);
  }
}
// 清除现有的canvas元素
function clearCanvases() {
  const container:any = document.getElementById('pdf-canvas-container');
  while (container.firstChild) {
    container.removeChild(container.firstChild);
  }
}
//渲染
async function renderPage(pageNumber:number) {
  const page = await pdfDoc.getPage(pageNumber);
  const viewport = page.getViewport({ scale: scale });
  const outputScale = window.devicePixelRatio || 2;

  // 为每一页创建一个唯一的canvas元素
  const canvas = document.createElement('canvas');
  canvas.id = `pdfCanvasPage${pageNumber}`; // 确保每个canvas的ID都是唯一的
  const canvasContext:any = document.getElementById('pdf-canvas-container');
  canvasContext.appendChild(canvas);
  
  const context = canvas.getContext('2d');

  canvas.width = Math.floor(viewport.width * outputScale);
  canvas.height = Math.floor(viewport.height * outputScale);
  canvas.style.width = Math.floor(viewport.width) + "px";
  canvas.style.height = Math.floor(viewport.height) + "px";

  const transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
  
  const renderContext = {
    canvasContext: context,
    transform: transform,
    viewport: viewport,
  };
  await page.render(renderContext).promise;
}
//防抖函数
function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void {
  let timeout: number | null = null;
  return (...args: Parameters<T>) => {
    if (timeout !== null) {
      clearTimeout(timeout);
    }
    timeout = window.setTimeout(() => {
      func(...args);
    }, wait);
  };
}
const debounceDelay = 300;
// 放大
const enlarge = debounce(() => {
  if (scale < 3) { // 限制最大放大倍数
    scale += 0.3;
    renderAllPages();
  }
}, debounceDelay)
// 缩小
const reduce = debounce(() => {
  if (scale > 1) { // 限制最小缩小倍数
    scale -= 0.3;
    renderAllPages();
  }
}, debounceDelay)
const init = (item:any) => {
  const url = item.typeUrl.split('&')
  pdfUrl = url[0];
  decryptionKey = url[1];
  loadAndRenderPDF();
}
</script>

兼容老版本改为 import 'pdfjs-dist/legacy/build/pdf.worker.mjs';
更老版本chrome下解密失败TypeError:structuredClone is not defined. 解决方案:
npm i core-js-pure

import structuredClone from 'core-js-pure/actual/structured-clone';
window.structuredClone = structuredClone;
微信图片_20241210155920.png