记录
如果能直接使用,那自然最好不过了,但考虑多种因素,比如权限问题,禁止用户去下载PDF、预览样式不统一(不同浏览器PDF预览的实现不同),所有最终放弃了该方式
看了很多例子,大部分都是围绕pdf.js
这个库展开的,所以我的选项也是围绕它去找的
最终找到几个不错的
pdfjs-dist
react-pdf
pdf-viewer
接下来我会依次介绍一下三个库的使用
其实就是pdfjs库,只是对其进行打包发布到npm了
直接根据官方文档的案例对比进行操作就行了
import { useEffect, useRef } from 'react'
import * as PDFJS from 'pdfjs-dist'
PDFJS.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.js`
interface Props {
fileUrl: string
}
const FilePDF = ({ fileUrl }: Props) => {
const pdfContainer = useRef<HTMLCanvasElement>(null)
const pdfCtx = useRef<CanvasRenderingContext2D | null>(null)
const pdfDoc = useRef<any>()
const pdfNumPages = useRef(0)
// 依次渲染所有页面
const renderPage = num => {
pdfDoc.current!.getPage(num).then(page => {
const viewport = page.getViewport({ scale: 1 })
pdfContainer.current!.width = viewport.width
pdfContainer.current!.height = viewport.height
page
.render({
viewport,
canvasContext: pdfCtx.current!
})
.promise.then(() => {
if (num < pdfNumPages.current) {
renderPage(num + 1)
}
})
})
}
useEffect(() => {
pdfCtx.current = pdfContainer.current!.getContext('2d')
PDFJS.getDocument(fileUrl).promise.then(pdfDoc_ => {
pdfDoc.current = pdfDoc_
pdfNumPages.current = pdfDoc_.numPages
renderPage(1)
})
}, [])
return (
<div className={'flex h-full w-full items-center justify-center rounded-lg'}>
<canvas ref={pdfContainer}></canvas>
</div>
)
}
export default FilePDF
这种实现比较繁琐,所以也就有了react-pdf
,对pdfjs-dist
进行了一层封装
效果展示