赞
踩
在vue项目中,有的功能需要对pdf进行操作,比如:预览、下载、打印等,但是没有组件库有pdf的插件,需要安装下载专门的pdf插件,这里对pdf操作做了整合,分享给大家。
示例使用的是vue-pdf组件库,如果大家有更好的插件可以进行交流学习~
话不多说,上代码!!!(vue基础的代码就不过多展示了)
一、安装插件
npm i vue-pdf
插件的github地址: https://github.com/FranckFreiburger/vue-pdf
二、在公共组件库新建PdfView文件夹,这里放封装好的组件,代码如下
- <template>
- <div class="pdfView">
- <div class="show">
- <!--分页显示-->
- <pdf
- ref="pdf"
- :src="pdfUrl"
- :page="pageNum"
- :rotate="pageRotate"
- @password="password"
- @progress="loadedRatio = $event"
- @loaded="onLoadSuccess"
- @page-loaded="pageLoaded($event)"
- @num-pages="pageTotalNum = $event"
- @error="pdfError($event)"
- @link-clicked="page = $event"
- >
- </pdf>
- <!--整页显示-->
- <!-- <pdf
- v-loading="loading"
- element-loading-text="拼命加载中"
- element-loading-spinner="el-icon-loading"
- element-loading-background="rgba(0, 0, 0, 0.8)"
- v-for="i in numPages"
- :key="i"
- :src="pdfUrl"
- :page="i"
- @error="pdfError($event)"
- ref="pdf"
- ></pdf> -->
- </div>
-
- <div class="pdf_footer">
- <div class="info">
- <div>当前页数/总页数:{{ pageNum }}/{{ pageTotalNum }}</div>
- <!-- <div>进度:{{ loadedRatio }}</div> -->
- <!-- <div>页面加载成功: {{ curPageNum }}</div> -->
- </div>
- <div class="operate">
- <el-button-group>
- <el-button type="primary" icon="el-icon-arrow-left" style="border-radius: 30px 0 0 30px" @click.stop="prePage">上一页</el-button>
- <el-button type="primary" @click.stop="nextPage" style="border-radius: 0 30px 30px 0">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
- </el-button-group>
- <el-button-group>
- <el-button type="primary" style="border-radius: 30px 0 0 30px" @click="scaleD">放大</el-button>
- <el-button type="primary" style="border-radius: 0 30px 30px 0" @click="scaleX">缩小</el-button>
- </el-button-group>
- <!-- <el-button type="primary" @click="fileDownload(pdfUrl, 'pdf文件')">
- 下载
- <i class="el-icon-download"></i>
- </el-button> -->
- </div>
- </div>
- </div>
- </template>
-
- <script>
- import pdf from "vue-pdf";
- export default {
- name: "vue_pdf_preview",
- props: {
- // 当前pdf路径
- pdfUrl: {
- type: String,
- default: "",
- },
- },
- components: {
- pdf,
- },
- data() {
- return {
- // 总页数
- pageTotalNum: 1,
- // 当前页数
- pageNum: 1,
- // 加载进度
- loadedRatio: 0,
- // 页面加载完成
- curPageNum: 0,
- // 放大系数 默认百分百
- scale: 100,
- // 旋转角度 ‘90’的倍数才有效
- pageRotate: 0,
- // 单击内部链接时触发 (目前我没有遇到使用场景)
- page: 0,
- // 当前页数
- numPages: 1,
- // 预览路径
- localUrl: '',
- loading: true
- };
- },
- watch: {
- pdfUrl: {
- handler(newVal,oldVal) {
- this.localUrl = "";
- this.localUrl = newVal;
- let loadingTask = pdf.createLoadingTask(this.localUrl);
- loadingTask.promise.then(pdf => {
- this.numPages = pdf.numPages;
- this.loading = false;
- console.log('this.numPages', this.numPages)
- }).catch((err) => {
- console.error('pdf加载失败', err)
- })
- },
- immediate: true
- }
- },
- computed: {},
- created() {},
- mounted() {},
- methods: {
- onLoadSuccess(pdf) {
- // PDF加载成功后,可以将初始页码设置为第一页
- this.pageNum = 1;
- },
- //下载PDF
- fileDownload(data, fileName) {
- let blob = new Blob([data], {
- //type类型后端返回来的数据中会有,根据自己实际进行修改
- type: "application/pdf",
- });
- let filename = fileName || "pdf.pdf";
- if (typeof window.navigator.msSaveBlob !== "undefined") {
- window.navigator.msSaveBlob(blob, filename);
- } else {
- var blobURL = URL.createObjectURL(blob);
- // 创建隐藏<a>标签进行下载
- var tempLink = document.createElement("a");
- tempLink.style.display = "none";
- tempLink.href = blobURL;
- tempLink.setAttribute("download", filename);
- if (typeof tempLink.download === "undefined") {
- tempLink.setAttribute("target", "_blank");
- }
- document.body.appendChild(tempLink);
- tempLink.click();
- document.body.removeChild(tempLink);
- window.URL.revokeObjectURL(blobURL);
- }
- },
- //打印
- pdfPrintAll() {
- this.$refs.pdf.print();
- },
- //放大
- scaleD() {
- this.scale += 5;
- this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
- },
-
- //缩小
- scaleX() {
- // scale 是百分百展示 不建议缩放
- if (this.scale == 100) {
- return;
- }
- this.scale += -5;
- console.log(parseInt(this.scale) + "%");
- this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
- },
- // 切换上一页
- prePage() {
- var p = this.pageNum;
- p = p > 1 ? p - 1 : this.pageTotalNum;
- this.pageNum = p;
- },
- // 切换下一页
- nextPage() {
- var p = this.pageNum;
- p = p < this.pageTotalNum ? p + 1 : 1;
- this.pageNum = p;
- },
- // pdf 有密码 则需要输入秘密
- password(updatePassword, reason) {
- updatePassword(prompt('password is "test"'));
- console.log("...reason...");
- console.log(reason);
- console.log("...reason...");
- },
- // 页面加载成功 当前页数
- pageLoaded(e) {
- console.log("pageLoaded",e);
- this.$emit("current", e);
- this.curPageNum = e;
- },
- // 异常监听
- pdfError(error) {
- console.error('异常监听', error);
- },
- // getNumPages() {
- // let loadingTask = pdf.createLoadingTask(this.pdfUrl);
- // loadingTask.promise.then(pdf => {
- // this.numPages = pdf.numPages;
- // console.log('this.numPages', this.numPages)
- // }).catch((err) => {
- // console.error('pdf加载失败')
- // })
- // },
- },
- };
- </script>
-
- <style lang="scss" scoped>
- .pdfView {
- padding: 20px;
- .show {
- overflow: auto;
- margin: auto;
- max-width: 100%;
- //height: 80vh;
- max-height: 580px;
- border: 2px solid #eee;
- border-radius: 6px;
- background-color: #eeeeee;
- // 滚动条样式
- &::-webkit-scrollbar {
- width: 10px;
- }
- &::-webkit-scrollbar-thumb {
- background-color: #999;
- border-radius: 6px;
- }
- &::-webkit-scrollbar-track {
- background-color: transparent;
- border-radius: 6px;
- }
- }
- .pdf_footer {
- position: sticky;
- bottom: 0;
- left: 0;
- right: 0;
- padding: 10px 0;
- background-color: rgba(255, 255, 255, 0.5);
- .info {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-around;
- div {
- width: 30%;
- }
- }
- .operate {
- margin: 10px 0 0;
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- div {
- // width: 80px;
- text-align: center;
- font-size: 15px;
- }
- .btn {
- cursor: pointer;
- margin: 5px 10px;
- width: 120px;
- border-radius: 10px;
- padding: 5px;
- color: #fff;
- background-color: #3dcbbc;
- }
- }
- }
- }
- </style>
这里给出了几种展示方式,有分页显示,有整页显示。按照项目需求可自行进行调整。
三、在页面你需要的地方引用
import PdfView from "@/components/PdfView"; import pdf from 'vue-pdf'; export default { components:{pdf}, data(){ return{ pdf_img_url: null,//pdf文件路径 } }, methods:{ downloadPDF(){ let url=this.pdf_img_url let newTab = window.open(url, '_blank'); // 新窗口加载完后打印 newTab.onload = function() { newTab.focus(); newTab.print(); }; }, printPdf() { console.log('this???????',this.$refs.pdf); this.$refs.pdf.pdfPrintAll() }, } }
- <el-dialog
- title="PDF文件预览"
- :visible.sync="PdfViewVisible"
- append-to-body
- lock-scroll
- width="50%"
- :before-close="handleClosePdf"
- >
- <el-button @click="downloadPDF">下载</el-button>
- <i class="el-icon-printer" @click="printPdf" style="cursor: pointer;float: right;font-size: 25px;"></i>//这是打印事件
- <pdf-view :pdfUrl="pdf_img_url" ref="pdf" @load="onPDFLoaded"></pdf-view>
- </el-dialog>
我这里放在了dialog中使用,可以根据自己实际需要的场景来进行使用。
预览是在当前页面打开的,不需要打开浏览器新窗口。
打印也是在当前页面打开了打印的窗口,但是需要注意有乱码的情况产生,这时需要更改插件的源文件。如果你的项目没有要求当前页面还是新窗口打开,那可以直接使用window.print(),可以参考下载的方法,调出浏览器自带的打印、下载事件(这个比较成熟,可以直接用)。
四、运行示例
好啦,这次的分享就进行到这了。博主也是第一次使用这个插件,在不断学习中,如果有朋友发现问题可进行评论交流学习。勿喷勿喷!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。