[VUE]vue-pdf打印、下载、Dialog

 

采用store存储 dialogVisible的状态可以实现非父子组件的通信

//路径:src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import pdfDialog from './modules/pdfDialog'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    pdfDialog,
  },
})

export default store
//路径:src/store/modules/pdfDialog.js
export default {
    state: {
        dialogVisible:false,
    },
    mutations: {
        setDialogVisible(state,dialogVisible){
            state.dialogVisible=dialogVisible
        },
    },
    actions: {
    }
}

在页面的index文件中写上两个组件

<template>
  <div class="detailsDiv">
    <pdf-dialog></pdf-dialog>
    <pdf-dialog-show></pdf-dialog-show>
  </div>
</template>

<script>
import PdfDialog from './components/pdfDialog.vue';
import PdfDialogShow from './components/pdfDialogShow.vue';
export default {
  components: {  PdfDialog, PdfDialogShow },
  methods: {},
};
</script>

<style lang="sss" scoped>
.detailsDiv {
  display: flex;
  justify-content: center;
  height: 100%;
  width: 100%;
}
</style>

在显示组件pdfDialog中设置一个bottom,点击后使dialogVisible为true(显式地提交 (commit) mutation使dialogVisible为true)

<template>
  <div class="pdfDialog">
    <div class="divHeader">
      {{ title }}
      <div class="clickBotton">
        <el-button size="mini" @click="handleReportButton()"
          >查看完整文章</el-button
        >
      </div>
    </div>
    <div class="cutLine"></div>
    <div class="divComponent">
      <img
        src="../showFiles/1.png"
        alt="建筑工程地下室防水施工技术分析"
        style="width: 90%; height: 90%"
      />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: "研究成果",
      test: true,
    };
  },
  methods: {
    handleReportButton() {
      this.$store.commit("setDialogVisible", true);
      // console.log(this.$store.state.pdfDialog.dialogVisible);
    },
  },
};
</script>

<style lang="sss" scoped>
.pdfDialog {
  width: 50%;
  height: 40%;
  background: rgba(1, 159, 245, 0.1);
}
.divHeader {
  width: 100%;
  height: 13%;
  display: flex;
  justify-content: space-around;
  align-items: center;
  position: relative;
}
.clickBotton {
  position: absolute;
  right: 0;
  width: 30%;
  height: 70%;
}
.cutLine {
  position: relative;
  width: 100%;
  height: 4px;
  background: rgba(1, 159, 245, 0.4);
}
.cutLine::after {
  position: absolute;
  left: 0;
  content: "";
  width: 8.125rem;
  height: 4px;
  background: rgb(1, 159, 245);
  transition: all 0.5s;
}
.divComponent {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: calc(100% - 2.8125rem);
  padding: 0.625rem 0.9375rem;
}
.pdfDialog:hover .cutLine::after {
  width: 100%;
}
.divHeader ::v-deep .el-button {
  color: #ffffff;
  background: transparent;
  width: 20%;
}
.divHeader ::v-deep .el-button--mini {
  padding: 7px 0px;
}
.divHeader ::v-deep .el-button:hover {
  background: #ff9549cc;
}
</style>

在弹出组件pdfDialogShow中设置pdf页面的“打印”“下载”“返回”等按钮

遇到的问题:

使用vue-pdf读取本地项目PDF文件报错

原因及解决方法:读取PDF文件时,路径不合法,导致读取不到文件; 在vue-cli3脚手架搭建的项目中,读取本地的PDF文件需要放在public / static下,引用时不能写相对路径,采用/ static/xxx.pdf的路径方式进行引用(/ 代表public)

<template>
  <el-dialog
    :visible.sync="$store.state.pdfDialog.dialogVisible"
    :modal="false"
  >
    <div class="pdfDialogShow">
      <div class="header">
        {{ title }}
        <el-button icon="el-icon-back" @click="handleBackClick()"
          >返回</el-button
        >
      </div>
      <div class="architecturePdf">
        <pdf
          ref="pdf"
          v-for="i in numPages"
          :key="i"
          :src="pdfSrc"
          :page="i"
        ></pdf>
      </div>
      <div class="pdfButton">
        <el-button icon="el-icon-printer" @click="printPdf()">打印</el-button>
        <el-button icon="el-icon-download" @click="downloadClick()"
          >下载报告</el-button
        >
      </div>
    </div>
  </el-dialog>
</template>

<script>
import pdf from "vue-pdf";
export default {
  components: {
    pdf,
  },
  data() {
    return {
      url: "/static/pdf/show.pdf  ",
      pdfSrc: "",
      title: "建筑工程地下室防水施工技术分析pdf",
      numPages: undefined,
      test: true,
    };
  },
  methods: {
    getNumPages() {
      // 有时PDF文件地址会出现跨域的情况,最好处理一下
      let loadingTask = pdf.createLoadingTask(this.url);
      loadingTask.promise
        .then((pdf) => {
          this.pdfSrc = loadingTask;
          this.numPages = pdf.numPages;
        })
        .catch((err) => {
          console.error("pdf 加载失败");
        });
    },
    printPdf() {
      this.$refs.pdf[0].print();
    },
    handleBackClick(){
      this.$store.commit("setDialogVisible", false);
    },
    downloadClick() {
      var a = document.createElement("a");
      a.setAttribute("href", this.url);
      a.setAttribute(
        "download",
        "建筑工程地下室防水施工技术分析.pdf"
      );
      document.body.appendChild(a);
      a.click();
    },
  },
  mounted() {
    this.getNumPages();
  },
};
</script>

<style lang="sss" scoped>
.pdfDialogShow {
  z-index: 999999;
  background-color: #ececec;
  height: 100%;
  width: 100%;
  pointer-events: all;
}
.header {
  display: flex;
  width: 100%;
  height: 5%;
  padding-left: 3%;
  background-color: #fff;
  align-items: center;
  font-size: 1.3rem;
}
.architecturePdf {
  position: absolute;
  left: 15%;
  width: 70%;
  top: 7%;
  height: 85%;
  overflow-y: auto;
}
.pdfButton {
  position: absolute;
  left: 15%;
  width: 70%;
  top: 92%;
  height: 5%;
  background-color: #fff;
  border-top: 1px solid #ececec;
  display: flex;
  justify-content: center;
  align-items: center;
}
>>> .el-button {
  width: 20%;
  height: 70%;
  background-color: #1e2c7c;
  color: #fff;
}
.header >>> .el-button {
  margin-left: 65%;
  width: 8%;
  background-color: #fff;
  color: #000;
}
>>> .el-dialog__header {
  padding: 0;
  padding-bottom: 0;
}
>>> .el-dialog {
  margin: 0 !important;
  width: 100%;
  height: 100%;
}
>>> .el-dialog__body {
  padding: 0;
  width: 100%;
  height: 100%;
}
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值