需求

因公司需要对设备上传的pdf文件进行展示,或者自行上传pdf文件等
并且可以对pdf文件进行打印

思路

在做之前因为要考虑到组件的复用性,所以选择了对上传组件进行封装(这里我使用的element ui)

  1. 在封装之前我需要对上传可能存在的情况进行梳理;
    1.对文件类型(图片,音频,文件…)
    2.文件大小(mb)
    3.文件格式(“.jpg,.mp4,.gif,.pdf,.JPG,.MP4,.GIF,.PDF”…)
    4.文件数量
  2. 操作方式
    1.点击上传
    2.拖拽上传

组件代码(components/PhotoUploading)

<template>
  <div class="PhotoUploading">
    <el-upload
      ref="upload"
      class="upload-demo"
      :action="actionsUrl"
      :on-success="successFn"
      :on-exceed="onExceed"
      :before-upload="beforeUpload"
      :before-remove="beforeRemove"
      :on-change="onChangeFn"
      :auto-upload="false"
      :file-list="fileLists"
      :on-error="onErrorFn"
      :accept="fileFormat"
      :limit="limitQuantity"
      drag
      multiple
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      <div class="el-upload__tip" style="font-size: 14px" slot="tip">
        只能上传 {{ strString }} 文件,一次性最多上传
        {{ limitQuantity }} 个文件,每个文件不得超过 {{ sizeLimit }}MB
      </div>
    </el-upload>
  </div>
</template>

<script>
import { debounce } from "@/utils";
export default {
  data() {
    return {
      fileList: [], // 图片路径列表
      fileIdList: [], // 存储上传图片后的id值
      fileSize: 2097152, // 上传文件最大值 2MB=2097152  5MB=5242880
      limitList: [], // 选中的文件
      errList: [], //上传失败
      strString: "",
      fileLists: [], // 选中列表文件
    };
  },
  watch: {
    isTrue(item, item1) {
      console.log("清除上传图片");
      this.fileList = [];
      this.fileIdList = [];
      this.limitList = [];
      this.fileLists = [];
    },
    upLoads(item, items) {
      if (!this.fileLists.length) {
        this.$message({ type: "error", message: "请选择上传的文件" });
      }
      this.$refs.upload.submit();
    },
  },
  props: {
    // 上传路径 默认是系统设置里面的路径
    actionsUrl: {
      type: String,
      require: false,
      default:....,//上传路径
    },
    // 判断弹框是否关闭清空数据
    isTrue: {
      type: Boolean,
      require: false,
      default: "false",
    },
    // 图片宽度大小
    isWidth: {
      type: String,
      require: false,
    },
    // 这个状态改变的时候就是上传图片所以是必填
    upLoads: {
      type: Boolean,
      require: true,
    },
    // 文件格式
    fileFormat: {
      type: String,
      require: false,
      default: ".jpg,.mp4,.gif,.pdf,.JPG,.MP4,.GIF,.PDF",
    },
    // 限制数量
    limitQuantity: {
      type: Number,
      require: false,
      default: 5,
    },
    // 文件大小限制
    sizeLimit: {
      type: Number,
      require: false,
      default: 2,
    },
  },
  mounted() {
    // 图片上传宽度
    if (this.isWidth !== undefined) {
      let PhotoUploading = document.querySelector(".PhotoUploading");
      PhotoUploading.style.width = this.isWidth;
    }
  },
  created() {
    let str = this.fileFormat.split(",");
    this.strString = str.join(" ");
    // console.log(this.FileFormat);
    let num = this.sizeLimit * 1024 * 1024;
    this.fileSize = num;
  },
  methods: {
    // 选中的图片
    onChangeFn(e, fileList) {
      console.log(e);
      this.limitList = fileList;
      this.fileLists = this.fileLists.length ? this.fileLists : [];
      // this.limitList.push(e);
      this.limitFn();
    },

    // 文件列表删除效果
    beforeRemove(file, fileList) {
      console.log(file, fileList);
      let list = fileList.filter((res) => {
        return res.name !== file.name;
      });
      this.fileLists = list;
    },

    // 文件上传之前的钩子
    beforeUpload(file) {
      console.log(file);
    },

    // 图片上传成功时的钩子
    successFn(response, file, fileList) {
      // console.log(response, file, fileList);
      this.fileIdList = fileList;
      this.fileLsitfn();
    },

    // 文件上传失败时的钩子
    onErrorFn(err, file, fileList) {
      if (err.type === "error") {
        this.errList.push(file);
      }
      this.errorFn();
    },

    // 上传失败
    errorFn: debounce(function () {
      let errArr = [];
      this.errList.map((res) => {
        errArr.push(res.name);
      });
      this.$message({
        type: "error",
        message: `${errArr.map((res) => {
          return res + "/";
        })}上传失败`,
      });
    }, 500),

    limitFn: debounce(function () {
      let list = [],
        testList = [];
      // console.log(this.limitList);
      this.limitList.map((res) => {
        let name = res.name.substr(-4, 4);
        // 获取传递过来的文件要求
        let arr = this.fileFormat.split(",");
        let index = arr.map((item) => {
          return name !== item;
        });
        // 文件限制2MB和文件要求
        if (
          res.size < this.fileSize &&
          !index.every((items) => {
            return items === true;
          })
        ) {
          testList.push(res);
        } else {
          list.push(res);
        }
      });
      if (list.length)
        this.$message({
          type: "error",
          message: `只能上传  ${this.strString}  文件,每张不得超过 ${this.sizeLimit}MB,`,
        });
      // console.log(testList);
      this.fileLists = testList;
    }, 500),

    // 上传完之后添加列表
    fileLsitfn: debounce(function () {
      let list = [];
      this.fileIdList.map((res) => {
        // console.log(res);
        list.push({
          status: res.status,
          name: res.name,
          url: res.response.data[0].fileId,
        });
      });
      this.fileList = list;
      this.$emit("fileId", this.fileList);
    }, 500),

    // 上传超过限制的提示
    onExceed(files, fileList) {
      this.$message({
        type: "error",
        message: `上传的图片超过最大限制,一次性最多上传${this.limitQuantity}`,
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.PhotoUploading {
  // width: 80%;
  ::v-deep .el-upload {
    width: 100%;
    .el-upload-dragger {
      width: 100%;
    }
  }
}
</style>

组件代码使用(哪里需要哪里引用)

展示

<template>
  <div class="app-container">
    <!-- 上传 -->
    <div class="UploadBox">
      <PhotoUploading
        @fileId="fileListFn"
        :is-width="'80%'"
        :is-true="istrue"
        :up-loads="upLoads"
        :limitQuantity="1"
        @disabledBtn="disFn"
        file-format=".pdf,.PDF"
      />
    </div>
  </div>
</template>
    
    <script>
import PhotoUploading from "@/components/PhotoUploading";
export default {
  name: "PagePermission",
  components: { PhotoUploading },
  data() {
    return {};
  },

  methods: {
    // 文件大于5mb禁用按钮
    disFn(res) {
      // console.log(res);
      this.disisTrue = res;
    },
    // 图片上传返回的列表
    fileListFn(fileList) {
      this.fileList = fileList;
      // 在上传图片下
      if (this.fileList.length == 1) {
        let imgList = [];
        this.fileList.map((res) => {
          imgList.push(res.url);
        });
		//接口位置
        this.fileList = [];
        this.istrue = true;
      } else {
        this.$message({ type: "error", message: "请先上传文件" });
      }
    },
  },
};
</script>
   

我这边上传掉接口后端

blob 的方式进行存取的
这个优点是能保护数据,甚至可以使用 blob 实现动态图片传输

对上传的pdf进行展示,打印

展示
在这里插入图片描述
打印
在这里插入图片描述

这里我借助的插件
vue-pdf
使用

<template>
  <div>
    <el-button
          class="filter-item el-button-new-wid"
          @click="printImg"
          >打印</el-button
        >
      <div title="文件预览" width="50%">
        <div ref="printContent">
          <Pdf v-for="i in numPages" :key="i" :src="src" :page="i" />
        </div>
      </div>
  </div>
</template>
  
  <script>
import {html2canvas} from "html2canvas";
import {printJS} from "print-js";
import Pdf from "vue-pdf";
export default {
  components: {
    Pdf,
  },
  data() {
    return {
      numPages: undefined,
      src: "",
      fileUrl: "",

      ruleForm: {
        reviewedRemark: "",
      },
      rules: {},
      enumCardAssessReviewedStatus: "",
      reviewedRemark: "",
    };
  },
  created() {
      console.log(this.fileUrl);
      接口({ id: this.$route.query.id }).then(
        (res) => {
          this.fileUrl =
            process.env.VUE_APP_BASE_API_CAPY +
            "从服务器存储路径" +
            res.data.reportPath;
          this.enumCardAssessReviewedStatus =
            res.data.enumCardAssessReviewedStatus;
          this.reviewedRemark = res.data.reviewedRemark;
      
          this.src = Pdf.createLoadingTask(this.fileUrl);
          this.src.promise.then((pdf) => {
            console.log(pdf);
            this.numPages = pdf.numPages;
          });
        }
      );
  },
  methods: {
    returnlist() {
      if (this.$route.query.JumpId === "PGJG") {
        this.$store.dispatch("tagsView/delView", this.$route);
        this.$router.push({
          name: "evaluationResults",
          query: {
            id: this.$route.query.ids,
          },
        });
      } else {
        this.$store.dispatch("tagsView/delView", this.$route);
        this.$router.push({ name: "Auditreport" });
      }
    },
    // 转图片之后打印
    printImg() {
      html2canvas(this.$refs.printContent, {
        backgroundColor: null,
        useCORS: true,
        windowHeight: document.body.scrollHeight,
      }).then((canvas) => {
        const url = canvas.toDataURL();
        printJS({
          printable: url,
          type: "image",
          documentTitle: this.printName,
        });
      });
    },
  


  },
};
</script>
 
  
 

完成!!留作记录!

GitHub 加速计划 / vu / vue
207.55 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:3 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 5 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐