vue3使用pdfjs-dist
如果需要使用点击跳页的话,用一个变量控制 页码,然后在canvas上换成变量,每次跳页就+-数字就好,位置可以自己定位到需要位置。当前时间是可以使用的,刚实现过,后续如果不可以用了,可能是安装东西的版本迭代了。重新安装的时候版本不同了。如果不知道在哪,可以点开node_modules找到pdfjs-dist对应去改一下就好。然后 找到对应位置:// vite.config.ts 文件。版本会引起报
效果展示:
首先我的版本是:
"vue": "^3.3.4",
"vite": "^4.2.1",
"pdfjs-dist": "^4.0.379",
然后安装 :
npm i pdfjs-dist
如果遇到 报错:
Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides) node_modules/pdfjs-dist/build/pdf.mjs:17349:53: 17349 │ /******/ __webpack_exports__ = globalThis.pdfjsLib = await (globalThis.pdfjsLibPromise = __webpack_exports__);
- 原因:vite 不支持顶级的 async/await 语法,需要安装插件做兼容
- 解决:vite.config.ts 安装并引入 topLevelAwait
- npm install vite-plugin-top-level-await -D
然后 找到对应位置: // vite.config.ts 文件
import topLevelAwait from 'vite-plugin-top-level-await'export default ({ mode }: any) => {
return defineConfig({
plugins: [
topLevelAwait({
promiseExportName: '__tla',
promiseImportName: (i) => `__tla_${i}`
})
],
})
}
具体完整实现代码:
pdf组件
<template>
<div class="pdf-container">
<canvas v-for="pdfIndex in pdfPages" :id="`pdf-canvas-${pdfIndex}`" :key="pdfIndex" />
</div>
</template>
<script setup lang="ts">
import * as PDFJS from 'pdfjs-dist/legacy/build/pdf.mjs'
import * as PdfWorker from 'pdfjs-dist/legacy/build/pdf.worker.mjs'
import { nextTick, ref, Ref, watch } from 'vue'
import { isEmpty, debounce } from 'lodash-es'
const props: any = defineProps({
pdf: {
required: true
}
})
let pdfDoc: any = null
const pdfPages: Ref = ref(0)
const pdfScale: Ref = ref(1.3)
const loadFile = async (url: any) => {
// 设定pdfjs的 workerSrc 参数
PDFJS.GlobalWorkerOptions.workerSrc = PdfWorker
const loadingTask = PDFJS.getDocument(url)
loadingTask.promise.then(async (pdf: any) => {
pdfDoc = pdf // 保存加载的pdf文件流
pdfPages.value = pdfDoc.numPages // 获取pdf文件的总页数
await nextTick(() => {
renderPage(1) // 将pdf文件内容渲染到canvas
})
}).catch((error: any) => {
//可以用自己组件库弹出提示框
console.log(error)
})
}
const renderPage = (num: any) => {
pdfDoc.getPage(num).then((page: any) => {
page.cleanup()
const canvas: any = document.getElementById(`pdf-canvas-${num}`)
if (canvas) {
const ctx = canvas.getContext('2d')
const dpr = window.devicePixelRatio || 1
const bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1
const ratio = dpr / bsr
const viewport = page.getViewport({ scale: pdfScale.value })
canvas.width = viewport.width * ratio
canvas.height = viewport.height * ratio
canvas.style.width = viewport.width + 'px'
canvas.style.height = viewport.height + 'px'
ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
const renderContext = {
canvasContext: ctx,
viewport: viewport
}
page.render(renderContext)
if (num < pdfPages.value) {
renderPage(num + 1)
}
}
})
}
const debouncedLoadFile = debounce((pdf: any) => loadFile(pdf), 1000)
watch(() => props.pdf, (newValue: any) => {
!isEmpty(newValue) && debouncedLoadFile(newValue)
}, {
immediate: true
})
</script>
<style scoped lang="less">
.pdf-container {
width: 100%;
height: 100%;
overflow: auto; /* 启用滚动条 */
}
canvas {
width: 100%;
max-height: 100vh; /* 设置最大高度为视口高度 */
}
</style>
父组件:
<!-- pdf展示 -->
<div class="leftMain">
<PdfView :pdf="jsPdf" style="width: 100%;height:100%;"></PdfView>
</div>
。。。
import jsPdf from '../../../assets/pdf/pdf1.pdf'
如果需要使用点击跳页的话,用一个变量控制 页码,然后在canvas上换成变量,每次跳页就+-数字就好,位置可以自己定位到需要位置。
注意:
不同vite版本引用路径可能不同:
如果不知道在哪,可以点开node_modules找到pdfjs-dist对应去改一下就好
版本会引起报各种错,需要注意,实在不行复制错误搜索就好。。。
当前时间是可以使用的,刚实现过,后续如果不可以用了,可能是安装东西的版本迭代了。。重新安装的时候版本不同了
优化空间
不分页的话加载过大文件时速度很慢,可以懒加载 ,也可以分页
样式美化
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)