pdfjs-dist v3.x渲染pdf

发布时间 2023-08-25 17:04:37作者: 丁少华
import './App.css'
import * as pdfjsLib from "pdfjs-dist";
import { useEffect, useRef, useState } from 'react'

pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.bootcdn.net/ajax/libs/pdf.js/3.9.179/pdf.worker.min.js'

function App() {
  // 定义一些页面所需变量
  const [page, setPage] = useState(1);
  const [pages, setPages] = useState(0);
  const containerRef = useRef(null);
  const [pdfDocument, setPdfDocument] = useState(null);

  const renderPage = async (num, pdfDoc = pdfDocument) => {
    if (!pdfDoc) { return false }
    const pdfPage = await pdfDoc.getPage(num);
    const viewport = pdfPage.getViewport({ scale: 1.5 });
    const canvas = containerRef.current;
    canvas.width = viewport.width;
    canvas.height = viewport.height;
    const ctx = canvas.getContext("2d");
    const renderTask = pdfPage.render({
      canvasContext: ctx,
      viewport,
    });
    
    return renderTask.promise;
  }

  /**
   * 初始化pdfView
   */
  const initPdfView = async () => {
    const pdfPath = 'https://cos.dingshaohua.cn/aegis/1.pdf';
    const pdfDocument = await pdfjsLib.getDocument(pdfPath).promise;
    setPages(pdfDocument.numPages)
    setPdfDocument(pdfDocument);
    renderPage(page, pdfDocument);
  }

  /**
   * 下一页
   */
  const onNext = () => {
    if (page < pages) {
      setPage(page + 1)
    }
  }
  const onPrev = () => {
    if (page > 1) {
      setPage(page - 1)
    }
  }

  /**
   * 一些钩子
   */
  useEffect(() => {
    initPdfView();
  }, [])

  useEffect(() => {
    renderPage(page);
  }, [page])
  return (
    <div className='app'>
      <div className='skip'>
        <input type="number" min={1} max={pages} value={page} onChange={(e) => { setPage(Number(e.target.value)) }} />/{pages}
        <div onClick={onNext}>下一页</div> <div onClick={onPrev}>上一页</div>
      </div>
      <canvas ref={containerRef}></canvas>
    </div>
  )
}

export default App
.app{
  position: absolute;
  margin: auto;
  left: 0;
  right: 0;
  width: 50%; 
  height: 90%; 
  overflow: auto; 
}

.skip{
  background-color: aqua;
  width: 260px;
  position: fixed;
  right: 0;
  top: 0;
  padding: 10px;
  display: flex;
  z-index: 3;
}

.skip input{
  width:20%;
}

.skip div{
  background-color: gray;
  cursor: pointer;
  user-select: none;
  margin-left: 10px;
}

注意点:这里并没有使用pdf_viewer模式的渲染方式,和pdf_viewer比起来 这里要计算缩放度,而且比较糊,据说有svg模式 但是没有还没试