demo 展示
<template>
<div>
<div class="page-tool">
<span>文档预览</span>
<div>
<a-input-number @pressEnter="changePageNum" class="input" :controls="false" v-model:value="inputPageNum" size="small" placeholder="页面跳转" />
<span>/{{ state.numPages }}页</span>
</div>
</div>
<div class="pdf-box">
<!-- :height="state.height" :width="state.width" -->
<vue-pdf-embed v-if="state.source" ref="pdf" :source="state.source" :style="styleFn" :page="state.pageNum" class="showPdfContent" />
<div v-else class="no-pdf">
<a-upload> 请上传PDF格式文档 </a-upload>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, computed, ref } from 'vue'
import VuePdfEmbed from 'vue-pdf-embed'
import * as pdfjsLib from 'pdfjs-dist'
const inputPageNum = ref<number>(1)
const state = reactive({
source: '', // 预览pdf文件地址 /static/myPDF.pdf
pageNum: 1, // 当前页面
scale: 1, // 缩放比例
numPages: 0, // 总页数
// width: 400,
// height: 400,
})
const styleFn = computed(() => `transform:scale(${state.scale})`)
function getPdfUrl() {
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js'
const loadingTask = pdfjsLib.getDocument(state.source) // state.source pdf 路径
loadingTask.promise.then(pdf => {
state.numPages = pdf.numPages
})
}
/*
* 改变pdf当前页
*/
const changePageNum = () => {
if (inputPageNum.value >= 0 && inputPageNum.value <= state.numPages) {
state.pageNum = inputPageNum.value
} else {
inputPageNum.value = state.pageNum
return
}
}
onMounted(() => {
getPdfUrl()
})
</script>
<style scoped lang="less">
.vue-pdf-embed {
width: 100%;
height: 100%;
max-height: 100%;
}
.page-tool {
display: flex;
justify-content: space-between;
.input {
width: 50px;
margin-right: 10px;
}
}
// pdf 预览
.pdf-box {
position: relative;
width: 100%;
height: calc(100% - 60px);
background-color: rgb(216, 216, 216);
border: 1px solid rgb(216, 216, 216);
border-radius: 10px;
margin-top: 20px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.no-pdf {
margin: 0;
font-size: large;
}
</style>
踩雷
1 pdf 在本地项目中时
1、pdf 文件要放在 public/static 静态资源文件夹中
2、不能使用import 引入文件,而是直接使用路径 / static 。。。 /public省略
3、 pdf.worker.js 是以下在路径中将 pdf.worker.js 复制出来,然后放在 public 文件夹中
node_modules / .pnpm / pdfjs-dist@版本号 / node_modules / pdfjs-dist/ build/ pdf.worker.js
组件作用介绍
vue-pdf-embed
vue-pdf-embed 组件是用来 预览 pdfd
pdfjs-dist
pdfjs-dist 是用来计算 pdf 总页数的
vue3-pdfjs
该插件也是用来提取pdf总页数的,在这个demo没有用到嘞,
import { createLoadingTask } from 'vue3-pdfjs/esm' // 获得总页数
onMounted(() => {
const loadingTask = createLoadingTask(state.value.source) // state.value.source 是pdf路径
loadingTask.promise.then(pdf => {
state.value.numPages = pdf.numPages
console.log('vue-pdf-embed 总页数 ', pdf.numPages)
})
})
这个组件提取pdf总页数更加简单,直接放入图片路径即可,哈哈
修改样式
canvas 外面还包裹了一层 div 先将这层的 高度 设置为 100% 下面的canvas 才可以为高度设置 100%
// 修改预览样式
const styleFn = computed(() => `transform:scale(${state.scale});width:auto;height:100%`)
<style lang="less">
.vue-pdf-embed > div {
height: 100%;
}
.vue-pdf-embed canvas {
display: block;
height: 100% !important;
}
</style>
想要让 pdf 高度 100% ,宽度自适应 然后再盒子的中间展示,
自问自答:
.vue-pdf-embed canvas {
display: block;
width: auto !important;
height: 100% !important;
}
width 设置为 atuo,但是canvas 真实的width height 会影响布局,将右边的内容挤下去,貌似是这个原因,没看懂拉
然后就用了 position 居中布局了,over!
插件下载 warn 飘红记录
WARN deprecated dommatrix@1.0.3: dommatrix is no longer maintained. Please use @thednp/dommatrix.
over over ,下次有需求在补充的说