App 端(vue)上实现预览 PDF
方式一:JavaScript 插件实现 pdf 转 html
一、 引入第三方插件 PDF.js
在命令行中:
npm install pdfjs-dist
二、 在 vue.config.js 中定义 pdf.worker
在第三行
const pages = require("./build/pages");
const path = require("path");
//新增此行代码
pages["pdf.worker"] = "./node_modules/pdfjs-dist/build/pdf.worker.entry";
module.exports = {
publicPath: "./",
assetsDir: "assets",
pages: pages,
//以下省略...
三、 编写展示 pdf 的代码,可以做成组件(推荐),也可以直接协助想要展示的页面内
下面给出展示 pdf 的预览弹窗组件:
<template>
<mu-dialog :open.sync="pdfjsView" title="" width="55%" class="cpdf" append-to-body @close="pdfurl = null">
<div v-loading="loading" v-if="pdfurl" class="center" style="height: 600px">
<canvas v-for="data in canvasData" :key="data" :id="'the-canvas-' + data" class="canvasstyle"></canvas>
</div>
<div v-else style="font-size: 18px; text-align: center; font-weight: 900">没有PDF文件可以预览</div>
<span slot="footer">
<el-button @click="pdfjsView = false">取 消</el-button>
<el-button type="primary" @click="pdfjsView = false">确 定</el-button>
</span>
</mu-dialog>
</template>
<script type="text/ecmascript-6">
import PDFJS from 'pdfjs-dist'
export default {
name: 'CPdf',
components: {},
data() {
return {
pdfDoc: null, // pdfjs 生成的对象
pageNum: 1, //
pageRendering: false,
pageNumPending: null,
scale: 1.2, // 放大倍数
page_num: 0, // 当前页数
page_count: 0, // 总页数
maxscale: 2, // 最大放大倍数
minscale: 0.8, // 最小放大倍数
canvasData: [],
pdfjsView: false,
pdfurl: null,
loading: false
}
},
methods: {
renderPage(num) {
// 渲染pdf
const vm = this
this.pageRendering = true
const canvas = document.getElementById(`the-canvas-${num}`)
// Using promise to fetch the page
this.pdfDoc.getPage(num).then((page) => {
const viewport = page.getViewport(vm.scale)
// alert(vm.canvas.height)
canvas.height = viewport.height
canvas.width = viewport.width
// Render PDF page into canvas context
const renderContext = {
// canvasContext: vm.ctx,
canvasContext: canvas.getContext('2d'),
viewport
}
const renderTask = page.render(renderContext)
// Wait for rendering to finish
renderTask.promise.then(() => {
vm.pageRendering = false
if (vm.pageNumPending !== null) {
// New page rendering is pending
vm.renderPage(vm.pageNumPending)
vm.pageNumPending = null
}
})
})
vm.page_num = vm.pageNum
},
getUrl(url) {
this.pdfurl = url
this.pdfjsView = true
this.showPDf()
},
showPDf() {
const vm = this
this.loading = true
vm.canvasData = []
// PDFJS.workerSrc = '../../../static/PDF/pdf.worker.min.js'
PDFJS.getDocument(vm.pdfurl).promise.then((pdfDoc_) => {
// 初始化pdf
vm.pdfDoc = pdfDoc_
vm.page_count = vm.pdfDoc.numPages
for (let i = 0; i < vm.page_count; i += 1) {
vm.canvasData.push(i + 1)
}
return pdfDoc_
})
.then((pdfDoc_) => {
// 初始化pdf
vm.pdfDoc = pdfDoc_
vm.page_count = vm.pdfDoc.numPages
for (let i = 0; i < vm.page_count; i += 1) {
vm.renderPage(i + 1)
}
vm.loading = false
})
}
},
computed: {},
mounted() {
//
}
}
</script>
<style lang="scss" scoped type="text/css">
.cpdf {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
display: flex;
justify-content: center;
align-items: center;
.center {
text-align: center;
height: 100%;
overflow: auto;
padding-top: 20px;
.contor {
margin-bottom: 10px;
}
}
.page-foot {
position: fixed;
left: 0px;
bottom: 0px;
width: 100%;
height: 56px;
line-height: 56px;
background-color: #fff;
text-align: center;
z-index: 10;
.foot-button {
display: inline-block;
height: 56px;
position: relative;
top: -22px;
left: 20px;
}
}
}
</style>
四、调用(使用)pdf 展示方法
示例为调用 pdf 展示组件:先引入组件,然后调用其中实例方法。
<template>
<div id="app">
index
<mu-button @click="open"> open</mu-button>
<CPdf ref="pdf" />
<!-- <mu-button color="primary" @click="getMenu">getMenu</mu-button> -->
</div>
</template>
<script>
// import http from "../../utils/http.js";
import CPdf from "./pdf.vue";
export default {
name: "login",
components: {
CPdf
},
methods: {
open() {
this.$refs.pdf.pdfjsView = true;
this.$refs.pdf.getUrl('https://neilpatel.com/wp-content/uploads/2015/04/marketingplan.pdf');
}
}
};
</script>
方式二:使用 apicloud 的 pdf 预览模块
在 vue 组件中使用示例如下:
<template>
<div id="app">
<button @click="openPDF" :style="{ marginTop: '50px' }">点击</button>
</div>
</template>
<script>
export default {
name: "PdfTest",
data() {
return {
pdfReader: "",
};
},
methods: {
openPDF() {
let downloadUrl =
"http://192.168.40.223:8011/prj-trqz/ext/download/marketingplan.pdf";
this.pdfReader.open({
// path: "fs://" + downloadUrl.split("/")[downloadUrl.split("/").length - 1],
path: downloadUrl,
backBtn: {
size: {
w: 60,
h: 40,
},
bg: {
normal: "#282828",
highlight: "#d3d3d3",
},
title: {
text: "关闭",
size: 13,
color: "#fff",
},
corner: 4,
},
});
},
clearCache() {
this.pdfReader.clearCache();
},
},
mounted() {
this.pdfReader = window.api.require("pdfReader");
},
};
</script>