微信小程序(wepy) - PDF在线预览

874 阅读1分钟

1. 需求场景

【需求】PDF文件上传前后预览,需点击查看。

// 可根据文件路径区分是本地文件还是线上文件
var reg = RegExp(/wxfile/);
if (reg.exec('文件路径')) {
	// 本地文件
}else{
  // 线上文件
}

1.0本地文件预览

//预览本地文档
wx.chooseMessageFile({
    count: 1,     //能选择文件的数量
    type: 'file',   //能选择文件的类型,我这里只允许上传文件.还有视频,图片,或者都可以
    success(res) {
        let filePath = res.tempFiles[0].path; //微信临时文件路径
        wx.openDocument({
            fileType: 'pdf', // 需要写上文件类型才能预览,不让回找系统应用打开,体验不好
            filePath: filePath,
            showMenu: false,  //是否显示右上角菜单按钮  默认为 false
            success: function (res) {
                console.log('打开本地文档成功')
            },
            fail: function(error){
                console.log("打开本地文件失败")
            }
        })
    }
})

1.1 在线文件预览

wx.downloadFile({
     url: 'http://**.*****.***/reshaiwai/demo.pdf',      //要预览的 PDF 的地址
     success: function (res) {                           
       console.log(res);
       if (res.statusCode === 200) {                     //成功
         var Path = res.tempFilePath                     //返回的文件临时地址,用于后面打开本地预览所用
         wx.openDocument({
           fileType: 'pdf',       // 需要写上文件类型才能预览,不让回找系统应用打开,体验不好
           filePath: Path,                               //要打开的文件路径
           success: function (res) {
             console.log('打开 PDF 成功');
           }
         })
       }
     },
     fail: function (res) {
       console.log(res);                                  //失败
     }
 })

1.2 自定义文件上传组件(wepy)

【组件】1.组件内容

<!--
 * @Author: 刘小二
 * @Date: 2021-08-17 13:38:47
 * @LastEditors: 刘小二
 * @LastEditTime: 2021-09-22 11:48:47
 * @Description: 文件上传组件
 * @FilePath: /xxxx/src/components/base/upload/fileitem.wpy
-->
<template>
  <div class="lz-uploader">
    <div class="lz-uploader__wrapper">
      <!-- 预览样式 -->
      <div
        wx:for="{{ list }}"
        wx:key="index"
        class="uploader-item"
        data-index="{{ index }}"
        bindtap="onClickPreview"
      >
        <div class="lz-uploader__preview">
          <div class="preview-image">
            <image class="img" src="/static/image/file.png" mode="aspectFit" />
            <div class="preview-cover">
              <div class="preview-cover-text">{{ item.states }}</div>
            </div>
          </div>
          <div class="delete" data-index="{{ index }}" catch:tap="deleteItem">
            <van-icon name="cross" class="lz-uploader__preview-delete-icon" />
          </div>
        </div>
        <div class="fileName">{{ item.name }}</div>
      </div>
      <!-- 上传样式 -->
      <div class="lz-uploader__upload" bindtap="startUpload">
        <div class="lz-uploader__upload-image">
          <image class="img" src="/static/image/upload.png" mode="aspectFit" />
          <div class="preview-cover">
            <div class="preview-cover-text">上传文件</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import wepy from '@wepy/core';
wepy.component({
  props: {
    list: {
      type: Array,
      default: [],
    },
  },
  data: {
    maxFile: 1,
  },
  methods: {
    startUpload() {
      var that = this;
      if (that.list.length < that.maxFile) {
        wx.chooseMessageFile({
          count: 1,
          type: 'file',
          success(res) {
            if (res.tempFiles) {
              res.tempFiles.map((item, index) => {
                let newfilename = item.name;
                let validname = newfilename.substr(newfilename.indexOf('.'));
                if (validname == '.pdf') {
                  that.list.push(Object.assign({}, item, { states: 'pdf' }));
                } else {
                  wx.showToast({
                    title: '请选择pdf格式的文件',
                    icon: 'none',
                  });
                  that.list = [];
                }
              });
              if (that.list) {
                that.$emit('selectFile', { params: that.list[0] });
              }
            }
          },
        });
      }
    },
    onClickPreview(event) {
      const { index } = event.currentTarget.dataset;
      if (this.list[index].path) {
        var reg = RegExp(/wxfile/);
        if (reg.exec(this.list[index].path)) {
          let filePath = this.list[index].path; //微信临时文件路径
          wx.openDocument({
            fileType: 'pdf', // 需要写上文件类型才能预览,不让回找系统应用打开,体验不好
            filePath: filePath,
            showMenu: false, //是否显示右上角菜单按钮  默认为 false
            success: function (res) {
              console.log('打开本地文档成功');
            },
            fail: function (error) {
              console.log('打开本地文件失败');
            },
          });
        } else {
          wx.downloadFile({
            url: this.list[index].path, //要预览的 PDF 的地址
            success: function (res) {
              console.log(res);
              if (res.statusCode === 200) {
                var Path = res.tempFilePath; //返回的文件临时地址,用于后面打开本地预览所用
                wx.openDocument({
                  fileType: 'pdf', // 需要写上文件类型才能预览,不让回找系统应用打开,体验不好
                  filePath: Path, //要打开的文件路径
                  success: function (res) {
                    console.log('打开 PDF 成功');
                  },
                });
              }
            },
            fail: function (res) {
              console.log(res); //失败
            },
          });
        }
      }
    },
    deleteItem(event) {
      const { index } = event.currentTarget.dataset;
      this.list.splice(index, 1);
    },
  },
});
</script>
<style lang="less" scoped>
.uploader-item {
  display: flex;
  flex-direction: column;
  .fileName {
    text-align: center;
    width: 80px;
    font-size: 12px;
    font-family: PingFang SC;
    font-weight: 400;
    color: #000000;
  }
}
//
.lz-uploader {
  position: relative;
  display: inline-block;
  .lz-uploader__wrapper {
    display: flex;
    flex-wrap: wrap;
  }
}
//
.lz-uploader__upload {
  background: #f7f7f7;
  border-radius: 4px;
  position: relative;
  margin: 0 8px 8px 0;
  width: 80px;
  height: 80px;
  cursor: pointer;
  .lz-uploader__upload-image {
    display: block;
    overflow: hidden;
    .img {
      object-fit: cover;
      display: block;
      width: 40px;
      height: 40px;
      margin-top: 10px;
      margin-left: 20px;
    }
    .preview-cover {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      .preview-cover-text {
        position: absolute;
        bottom: 0;
        box-sizing: border-box;
        width: 100%;
        padding: 4px;
        color: #999999;
        font-size: 12px;
        text-align: center;
        background: #e6e6e6;
      }
    }
  }
}

// item
.lz-uploader__preview {
  background: #e7f7f1;
  border-radius: 4px;
  position: relative;
  margin: 0 8px 8px 0;
  width: 80px;
  height: 80px;
  cursor: pointer;
  .preview-image {
    display: block;
    overflow: hidden;
    .img {
      object-fit: cover;
      display: block;
      width: 40px;
      height: 40px;
      margin-top: 10px;
      margin-left: 20px;
    }
    .preview-cover {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      .preview-cover-text {
        position: absolute;
        bottom: 0;
        box-sizing: border-box;
        width: 100%;
        padding: 4px;
        color: #018a46;
        font-size: 12px;
        text-align: center;
        background: #c0f6e1;
      }
    }
  }
  .delete {
    position: absolute;
    top: 0;
    right: 0;
    width: 14px;
    height: 14px;
    background-color: rgba(0, 0, 0, 0.7);
    border-radius: 0 0 0 12px;
    .lz-uploader__preview-delete-icon {
      position: absolute;
      top: -2px;
      right: -2px;
      color: #fff;
      font-size: 16px;
      -webkit-transform: scale(0.5);
      transform: scale(0.5);
    }
  }
}
</style>
<config>
{
  usingComponents: {
      "van-icon": "module:@vant/weapp/dist/icon",
  }
}
</config>

【组件】2.组件使用

template

 <div class="card">
     <div class="page_little_title">
         <span class="text_title">上传简历</span>
      </div>
      <fileitem style="margin-left: 5px;" :list="resumeArr" @selectFile="selectFile_Resume"/>
 </div>

script

selectFile_Resume(param) {
      if(param && param.params){
        console.log('---' + JSON.stringify(param.params))
        this.uploadFile(param.params.path)
      }
 },

style

<style lang="less" scoped>
.card {
  margin: 10px;
  background: #fff;
  border-radius: 4px;
} 
.text_title{
  font-size: 15px;
  font-family: PingFang SC;
  font-weight: bold;
  color:#05A86C;
  margin-left: 10px;
}
.page_little_title{
  border-left: 4px solid;
  color:#05A86C;
  margin-bottom: 20rpx;
}
</style>