pdfjs-dist预览pdf
<template>
<div class="view">
<template v-for="item in pageNum" :key="item">
<canvas :id="`pdf-canvas-${item}`" class="pdf-page" />
</template>
</div>
<!-- <div class="footer">
<Button color="#006BE1" type="primary" @click="downLoadPDF" class="btn">
下载文件
</Button>
</div> -->
</template>
<script setup lang="ts">
import { reactive, toRefs, nextTick, watchEffect, defineProps } from "vue";
//@ts-ignore
import * as pdfjs from "pdfjs-dist";
//@ts-ignore
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
import { Toast, Button } from "vant";
// import { downloadFile } from "@/utils";
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
const props = defineProps({
url: { type: String, default: "" }, // pdf文件路径
});
const emit = defineEmits(["onRendered"]);
const state = reactive<any>({
pageNum: 0,
pdfCtx: null,
});
const resolvePdf = (url: string) => {
const loadingTask = pdfjs.getDocument(url);
loadingTask.promise.then((pdf: any) => {
state.pdfCtx = pdf;
state.pageNum = pdf.numPages;
nextTick(() => {
renderPdf();
});
});
};
const renderPdf = (num = 1) => {
state.pdfCtx.getPage(num).then((page: any) => {
const canvas: any = document.getElementById(`pdf-canvas-${num}`);
const ctx = canvas.getContext("2d");
const viewport = page.getViewport({ scale: 1 });
// 画布大小,默认值是width:300px,height:150px
canvas.height = viewport.height;
canvas.width = viewport.width;
// 画布的dom大小, 设置移动端,宽度设置铺满整个屏幕
const clientWidth = document.body.clientWidth;
canvas.style.width = clientWidth + "px";
// 根据pdf每页的宽高比例设置canvas的高度
canvas.style.height =
clientWidth * (viewport.height / viewport.width) + "px";
page.render({
canvasContext: ctx,
viewport,
});
if (num < state.pageNum) {
renderPdf(num + 1);
} else {
emit("onRendered");
Toast.clear(); // 取消加载loading
}
});
};
watchEffect(() => {
if (props.url) {
// 展示加载loading
Toast.loading({
message: "加载中...",
overlay: true,
forbidClick: true,
duration: 0,
});
resolvePdf(props.url);
}
});
const { pageNum, pdfCtx } = toRefs(state);
</script>
<style scoped>
.view {
padding-bottom: 1.5rem;
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
padding: 0.16rem 0.4rem 0.6rem;
display: flex;
align-items: center;
height: 1.5rem;
box-shadow: 0px -1px 0px rgba(49, 69, 106, 0.164254);
background-color: #fff;
}
.btn {
width: 100%;
}
.van-button {
border-radius: 0.1rem;
}
</style>