admin管理员组文章数量:1649178
环境说明:vue3 + vite + antdesignVue,使用pdfjs-dist插件,版本为2.16.105
提示:pdfjs-dist版本>3时,node版本需要>18
1、在vite.config.js中添加vite-plugin-top-level-await插件
npm install vite-plugin-top-level-await --save -dev
import topLevelAwait from 'vite-plugin-top-level-await'
export default defineConfig({
plugins: [topLevelAwait(),]
})
2、页面代码如下,支持滚动翻页、点击翻页、跳转页码
<template>
<div class="dy-pdf-preview">
<div v-if="pdfPagesNum === 0" class="loading">
<a-spin size="large" />
</div>
<div v-if="pdfPagesNum > 0" class="pdf-preview-wrap" @scroll="pdfScroll">
<div v-for="item in pdfPagesNum" :key="item" class="pdf-wrap">
<canvas :id="`pdf_canvas_${item}`" style="width: 100%; height: 100%"></canvas>
</div>
</div>
<div v-if="pdfPagesNum > 0" class="pdf-preview-footer">
<div class="left">
<div class="page">{{ currentPage }}/{{ pdfPagesNum }}</div>
<div class="jump">
跳转
<a-input
v-model:value="jumpPage"
size="small"
@blur="toPage(jumpPage)"
@keyup.enter="toPage(jumpPage)"
></a-input>
页
</div>
</div>
<div class="right">
<a-button type="primary" :disabled="currentPage <= 1" @click="prevPage">上一页</a-button>
<a-button type="primary" :disabled="currentPage >= pdfPagesNum" @click="nextPage"
>下一页</a-button
>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
// 文件id
fileId: String,
})
const pdfPagesNum = ref(0)
const currentPage = ref(1)
const jumpPage = ref(1)
const canvasHeight = ref(0)
function show() {
pdfPagesNum.value = 0
xxx.filePreview(props.fileId).then(res => {
handlePdf(res.data)
})
}
// 处理pdf
function handlePdf(file) {
let reader = new FileReader()
reader.readAsDataURL(file) //将文件读取为 DataURL
reader.onload = async function () {
//文件读取成功完成时触发
const pdfjs = await import('pdfjs-dist')
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.js', //pdfjs-dist版本>4时,路径为pdfjs-dist/build/pdf.worker.mjs,
import.meta.url
).href
const loadingTask = pdfjs.getDocument(reader.result)
loadingTask.promise.then(pdf => {
pdfPagesNum.value = pdf.numPages
// 等待dom渲染
nextTick(() => {
//处理
for (let i = 1; i <= pdf.numPages; i++) {
pdf.getPage(i).then(page => {
const canvas = document.getElementById('pdf_canvas_' + i)
const ctx = canvas.getContext('2d')
const viewport = page.getViewport({ scale: 3 })
// 画布大小,默认值是width:300px,height:150px
canvas.height = viewport.height
canvas.width = viewport.width
page.render({
canvasContext: ctx,
viewport,
})
})
}
})
})
}
}
// 滚动事件
function pdfScroll() {
if (pdfPagesNum.value > 0) {
nextTick(() => {
const firstCanvas = document.querySelector('.pdf-wrap')
if (canvasHeight.value !== firstCanvas.clientHeight) {
canvasHeight.value = firstCanvas.clientHeight
}
canvasHeight.value = firstCanvas.clientHeight
})
}
let pdfWrap = document.querySelector('.pdf-preview-wrap')
for (let i = 0; i < pdfPagesNum.value; i++) {
// 在滚动时,根据当前滚动距离和每页滚动的临界距离相比较,判断当前是第几页
if ((pdfWrap.scrollTop + canvasHeight.value * 0.1) / canvasHeight.value < i + 1) {
if (currentPage.value != i + 1) {
currentPage.value = i + 1
}
break
}
}
}
// 跳转
function toPage(val) {
if (isNaN(Number(val)) || !val || Number(val) < 1) {
jumpPage.value = 1
currentPage.value = 1
} else if (Number(val) > pdfPagesNum.value) {
jumpPage.value = pdfPagesNum.value
currentPage.value = pdfPagesNum.value
} else {
currentPage.value = Number(val)
}
currentPageChange()
}
// 上一页
function prevPage() {
if (currentPage.value > 1) {
currentPage.value--
currentPageChange()
}
}
// 下一页
function nextPage() {
if (currentPage.value < pdfPagesNum.value) {
currentPage.value++
currentPageChange()
}
}
// 页码切换事件
function currentPageChange() {
let pdfWrap = document.querySelector('.pdf-preview-wrap')
pdfWrap.scrollTop = canvasHeight.value * (currentPage.value - 1)
}
defineExpose({
show,
})
</script>
<style lang="scss" scoped>
.dy-pdf-preview {
width: 100%;
height: 100%;
.loading {
width: 100%;
height: 500px;
display: flex;
justify-content: center;
align-items: center;
}
.pdf-preview-wrap {
width: 100%;
height: calc(100% - 40px);
overflow-y: auto;
.pdf-wrap {
width: 100%;
position: relative;
}
}
.pdf-preview-footer {
position: absolute;
width: calc(100% - 36px);
height: 52px;
bottom: 3px;
border-top: 1px solid #e3e8ef;
display: flex;
align-items: center;
justify-content: space-between;
.left {
display: flex;
align-items: center;
.page {
margin-right: 15px;
}
.jump {
display: flex;
align-items: center;
.ant-input {
width: 38px;
margin: 0 5px 2px 5px;
}
}
}
.right {
width: 160px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
}
</style>
版权声明:本文标题:vue3 + vite + pdfjs-dist 实现pdf预览,支持翻页和滚动翻页 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1729505471a1203575.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论