准备:
- 下载pdfjs-dist
- 在vue项目public文件下创建pdfjs-dist目录
- 将下载的文件放入目录中(如下图所示)
第一步
在index.html中引入pdfjs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<!-- 引入pdfjs -->
<script src="/pdfjs-dist/pdf.min.js"></script>
<script type="module" src="/src/main.js"></script>
</body>
</html>
第二步
先要引入全局变量和配置
// 'pdfjs-dist/build/pdf' 是pdfjs挂在到window下的全局变量名称
const pdfjsLib = window['pdfjs-dist/build/pdf']
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs-dist/pdf.worker.min.js'
加载
这是一个loader方法
// 异步加载需要渲染的pdf文件
// props.src = 需要加载的文件地址
const loader = async () => {
pdfCtx = await pdfjsLib.getDocument(props.src).promise
pageNumber.value = pdfCtx.numPages
/**
nextTick(async () => {
const renders = []
for (let index = 1; index <= pdfCtx.numPages; index++) {
renders.push(render(index))
}
await Promise.all(renders)
// 渲染完成
})
*/
}
渲染
这是render函数
// number表示第几页
const render = async (number) => {
const page = await pdfCtx.getPage(number)
// 这里的一个canvas渲染pdf其中的一页
const canvas = document.getElementById(`pdf-canvas-${number}`)
const ctx = canvas.getContext('2d')
const viewport = page.getViewport({ scale: props.scale })
canvas.height = viewport.height
canvas.width = viewport.width
page.render({
canvasContext: ctx,
viewport
})
return true
}
完整代码(Vue3)
<script setup>
import { ref, onMounted, nextTick } from 'vue'
const pdfjsLib = window['pdfjs-dist/build/pdf']
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs-dist/pdf.worker.min.js'
const props = defineProps({
src: String,
scale: {
type: Number,
default: 1
}
})
// 注意不能使用响应式
let pdfCtx = null
const pageNumber = ref(0)
const loading = ref(false)
onMounted(() => {
if (props.src) {
loader()
}
})
const loader = async () => {
pdfCtx = await pdfjsLib.getDocument(props.src).promise
pageNumber.value = pdfCtx.numPages
nextTick(async () => {
const renders = []
for (let index = 1; index <= pdfCtx.numPages; index++) {
renders.push(render(index))
}
loading.value = true
await Promise.all(renders)
loading.value = false
})
}
const render = async (number) => {
const page = await pdfCtx.getPage(number)
const canvas = document.getElementById(`pdf-canvas-${number}`)
const ctx = canvas.getContext('2d')
const viewport = page.getViewport({ scale: props.scale })
canvas.height = viewport.height
canvas.width = viewport.width
page.render({
canvasContext: ctx,
viewport
})
return true
}
</script>
<template>
<div class="pdf">
<template v-for="number in pageNumber" :key="number">
<canvas :id="`pdf-canvas-${number}`"></canvas>
</template>
</div>
</template>
<style lang="less" scoped>
.pdf{
canvas{
width: 100%;
}
}
</style>