微信小程序开发之文件批量上传预览下载

1,967 阅读4分钟

前言
微信小程序文件批量上传预览下载
实现的功能
该篇介绍两种方式完成文件/图片的批量上传、下载、预览
界面如图下面所示分为图片和文件(word、pdf等):

1.转base64存储方式

由于后端必须存base64格式,所以中间没有走微信小程序的wx.uploadFile(后端不支持)

思路:

  • 调用wx.chooseImage之后获取到临时文件地址,
  • 再调用fs.readFile(var fs = wx.getFileSystemManager())读取文件转成base64格式,此时注意readFile是个异步读取的过程,需要解决异步问题,上传至后端成功之后,后端base64格式存储
  • 调用后端给的接口获取到这base64内容,利用fs.writeFile读取文件,将文件储存在用户内容中,可以得到这个写入文件地址(重),拿到这个写入文件地址之后就成功了!! 然后用wx.openDocument(Object object)打开文件,如果是需要预览图片:wx.previewImage ,需要直接展示在页面上,可以image标签即可src=临时文件地址

敲重点:

  • wx.uploadFile 必须要和后端配合支持,才可以使用,不然就会发送成功了,后端那边也接收不到参数,报错如下

  • fs.readFile只能一个一个读取文件,会涉及到异步,我用的是promise去解决,其实简便的方法可以用递归(有兴趣的可以去尝试),下面代码只介绍promise/async/await方法

图片批量上传、预览、下载

代码如下

  • 图片批量上传
   //批量上传图片,可以同时上传9张
uploadImg() {
    var that = this;
    wx.chooseImage({
      count: 9,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: function (res) {
        var successUp = 0; //成功
        var failUp = 0; //失败
        var length = res.tempFilePaths.length; //总数
        var count = 0; //第几张
        that.uploadOneByOne(res.tempFilePaths, successUp, failUp, count, length);
        console.log(res.tempFilePaths)
      },
    });
  },
      uploadOneByOne(imgPaths, successUp, failUp, count, length) {
    var that = this;
    console.log(888,imgPaths);
  //异步部分
  this.renderDate(imgPaths).then((res)=>{
    console.log('www',res);
    let objList=res;
    console.log('555',objList);
    wx.showToast({
      title: '请点击保存',
      icon: 'success',
      duration: 2000
    })
    that.setData({
      params:objList
    })

  })
console.log('yyy', this.renderDate(imgPaths))
  }, 
    getFilesitem(imgPaths){//返回的是promise对象
  return new Promise(function (resolve, reject) {
    var list=[]
    imgPaths.map(item=>{
      var obj 
      var radomStr = new Date().getTime()+that.getRadomNum(6);
        fs.readFile({
        filePath:item,
        success:  function (res){
          const arrayBuffer = new Uint8Array(res.data)
          const base64 = wx.arrayBufferToBase64(arrayBuffer)
          obj ={
            "certificateFileName":radomStr+".jpg",
            // "certificateContent":'data:image/jpg;base64,'+base64
            "certificateContent":base64
          } ;
        },
        complete: function(res){
          list.push(obj);
          console.log('xxxx',list)
          if(list.length==imgPaths.length){
            resolve(list)
          }
        }
      })
      });  
  })
},
async  renderDate(imgPaths){
  var  data=await this.getFilesitem(imgPaths); 
   console.log(data);
   return data
},

图片读取下载、预览、

   fs.writeFile({
            filePath: wx.env.USER_DATA_PATH +'/'+imgname,
            data: res.data.result.shvaFileContent,  
            encoding: 'base64',  
            success: res => {  
              console.log('图片路径',wx.env.USER_DATA_PATH +'/'+imgname)
              console.log('写数据',res)
              var pathcurrent=wx.env.USER_DATA_PATH +'/'+imgname
              var pathurls=[];
              pathurls.push(wx.env.USER_DATA_PATH +'/'+imgname)
              console.log('路径',pathcurrent,pathurls)
              wx.previewImage({
                current: pathcurrent, // 当前显示图片的http链接
                urls:pathurls,
                success:(res)=>{
                  wx.hideLoading()
                }
              })
            },
            fail: res => {
              console.log(res)
            }
          })

文件批量上传、预览、下载

文件上传

choosefilefun(){
    let _that = this;
    wx.chooseMessageFile({
      count: 10,
      type: 'file',
      success(res) {
        console.log(_that,' :this')
        // console.log(res, " :res")
        const tempFiles = res.tempFiles
        console.log('文件临时路径和名称',tempFiles)
        //异步部分
        _that.filesDate(tempFiles).then((res)=>{
          console.log('上传文件base64内容和名字',res)
          let objList=res;  
          wx.showToast({
            title: '请点击保存',
            icon: 'success',
            duration: 2000
          })
         that.setData({
            paramsword:objList
          })
          
        })

      }
    })
  },//上传文件异步
  async  filesDate(tempFiles){
    console.log('上传文件数据',tempFiles)
    var  data=await this.getFilesitemfile(tempFiles); 
     console.log(data);
     return data
  },
 //异步
 getFilesitemfile(tempFiles){//返回的是promise对象
  console.log(tempFiles)
  return new Promise(function (resolve, reject) {
    var list=[]
    tempFiles.map(item=>{
      console.log(item)
      var obj 
        fs.readFile({
        filePath:item.path,
        success:  function (res){
          console.log(item)
          const arrayBuffer = new Uint8Array(res.data)
          const base64 = wx.arrayBufferToBase64(arrayBuffer)
          console.log('文件base64',base64)
          obj ={
            "certificateFileName":item.name,
            // "certificateContent":'data:image/jpg;base64,'+base64
            "certificateContent":base64
          } ;
        },
        complete: function(res){
          list.push(obj);
          console.log('xxxx',list)
          if(list.length==tempFiles.length){
            resolve(list)
          }
        }
      })
      });  
  })
},

文件重读、预览

 fs.writeFile({
          filePath: wx.env.USER_DATA_PATH +'/'+imgname,
          data: res.data.result.shvaFileContent,  
          encoding: 'base64',  
          success: res => {  
            console.log('图片路径',wx.env.USER_DATA_PATH +'/'+imgname)
            console.log('写数据',res)
            //打开文件
            wx.openDocument({
            filePath: wx.env.USER_DATA_PATH +'/'+imgname,
            success: function (res) {
              wx.hideLoading()
              console.log('打开文档成功')
            },
            fail :function (res){
              console.log(res)
            }
          })
            // that.filesopen(wx.env.USER_DATA_PATH +'/'+item.certificateFileName)
          },
          fail: res => {
            console.log(res)
          }
        })
        }

2.使用wx.uploadFile配合第三方七牛(自家服务器)实现方式

1.需要后端使用文件流方式储存,我家后端储存方式文本,所以直接用的base64方式存储,如果后端支持,可以直接调用,

 wx.uploadFile({
          url: 'http://localhost:8080/upload/fileUpload' , //api
          filePath: tempFilePaths[0],//文件地址
          name: "file",
          header: {
          "Content-Type": "multipart/form-data"//必须支持文件流存储
          },
          //传的其他的参数
          formData: { 
            "user": "test",
          },
          success: function (res) {
            var data = res.data
            console.log(data)
            //do something
          }

2.七牛,请求后端得到七牛的token,需要后端去配置下

 wx.uploadFile({
          url: 'http://localhost:8080/upload/fileUpload' , //api
          filePath: tempFilePaths[0],//文件地址
          name: "file",
          header: {
          "Content-Type": "multipart/form-data"//必须支持文件流存储,
            'Authorization': wx.getStorageSync("access_token")//七牛token
          },
          //传的其他的参数
          formData: { 
            "user": "test",
          },
          success: function (res) {
            var data = res.data
            console.log(data)
            //do something
          }