Vant Uploader file upload and preview (pdf file)

Vant's component Uploader is used to upload files, and the uploaded files are previewed on the front end without involving the server. Achieved effect: If the PDF document has multiple pages, it can be slid up and down. It works normally on the mobile terminal, but there is no verification yet on the PC terminal.

I referred to this https://github.com/Hanpeng-Chen/hampton-demo-repo. There are several methods in it, and I only used one of them.

Table of contents

1. Install the plug-in

2. Introduce plug-ins

3. html part

4. js part

5. style part


1. Install the plug-in

npm install pdfjs-dist@^2.0.943

2. Introduce plug-ins

Note: The second line is very important. If you don’t use it, an error will be reported.

import pdfJS from 'pdfjs-dist';
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry');

3. html part

<template>
    <div class="hp-container">
        <div class="scroll-pdf-contanier" id="scrollPdfBox">
            <div v-for="index in pdfTotalPages" :key="index">
                <canvas :ref="`scrollPdfCanvas${index}`" class="content"></canvas>
            </div>
        </div>

        <van-uploader accept="file" result-type="text" v-model="fileList" multiple :max-count="1" class="uploader" ref="file" :after-read="afterRead" :before-read="beforeRead"></van-uploader>

       
        <van-row type="flex" justify="space-between" align="center">
            <van-col>
                <van-button @click="back">返回</van-button>
            </van-col>
            <van-col>
                <van-button type="info" @click="upload">上传文件</van-button>
            </van-col>
        </van-row>
    </div>
</template>

4. js part

import pdfJS from 'pdfjs-dist';
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry');

export default {
  name: 'uploadFile',
  components: {
  },
  data () {
    return {
      fileList: [],
      pdfTotalPages: 1,
      pdfData: null, // PDF的base64
      scale: 1 // 缩放值
    };
  },
  methods: {
    back () {
      this.$router.go(-1);
    },
    upload () {
      this.$refs.file.chooseFile();
    },
    // 文件读取前的回调函数,返回 false 可终止文件读取,支持返回 Promise
    beforeRead (file) {
      if (Array.isArray(file) && file.length > 1) {
        this.$toast('只能上传一份文件');
        return false;
      }

      if (file.type !== 'application/pdf') {
        this.$toast('请上传 pdf 格式的文件');
        return false;
      }
      return true;
    },
    // 文件读取完成后的回调函数
    afterRead (file) {
      const _this = this;
      var reader = new FileReader();
      reader.readAsDataURL(file.file); // 读取文件
      reader.onload = function (e) {
        const data = atob(reader.result.substring(reader.result.indexOf(',') + 1));
        _this.loadPdfData(data);
      }

      reader.onerror = () => {
        _this.$toast('文件解析失败,请重新上传');
        _this.fileList = [];
        _this.$refs.file.deleteFile();
      };
    },
    loadPdfData (data) {
      // 读取base64的pdf流文件
      this.pdfData = pdfJS.getDocument({
        data: data, // PDF base64编码
        cMapUrl: '',
        cMapPacked: true
      });

      this.renderScrollPdf();
    },
    renderScrollPdf () {
      this.pdfData.promise.then(pdf => {
        this.pdfTotalPages = pdf.numPages;
        this.renderScrollPdfPage(1);
      });
    },
    // 渲染连续滚动PDF
    renderScrollPdfPage (num) {
      this.pdfData.promise.then(pdf => {
        const numPages = pdf.numPages;
        pdf.getPage(num).then(page => {
          const canvas = this.$refs[`scrollPdfCanvas${num}`][0];

          // 为了预览的文件内容比较清晰,所以缩放值使用了3 
          const viewport = page.getViewport(3);

          console.log('viewport :>> ', viewport);
          canvas.height = viewport.height * this.scale;
          canvas.width = viewport.width * this.scale;
          const ctx = canvas.getContext('2d');
          const renderContext = {
            canvasContext: ctx,
            viewport: viewport
          };
          page.render(renderContext).then(() => {
            if (num < numPages) {
              this.renderScrollPdfPage(num + 1);
            }
          });
        });
      });
    }
  }
};

5. style part

// 隐藏文件上传样式
::v-deep .van-uploader {
    display: none;
}


// 防止预览文件超过一屏
.content{
  width: 750px;
}

Guess you like

Origin blog.csdn.net/zmzm227192/article/details/130357461