2021-06-30

微信小程序代码创建云数据库表并实现excel文件导入到云数据库表中及云数据库导出所有数据到excel

    在开发过程中,若一个表中记录字段长度不不统一时,如管理员数据中可能包含用户记录,导出数据到excel中时可能会出错误,本文介绍实现微信小程序云开发任意excel文件导入云数据库及从云数据库导出所有数据(字段长度可不统一)到excel。

页面实现效果图如下:

在这里插入图片描述
在这里插入图片描述

页面实现代码如下:

class页面:

//class.wxml
<button class="button" type="primary" bindtap="buildClass">新建班级</button>
<button class="button" type="primary" bindtap="lookClass">查看班级</button>

//class.wxss
.button{
  margin: 20rpx 0;
}

//class.js
Page({
  data: {
    collectionList: [],
    fileUrl: ''
  },
  onLoad: function (options) {
  },
  onShow: function () {
  },
  buildClass() {
    wx.navigateTo({
      url: '../newClass/newClass',
    })
  },
  lookClass() {
    wx.navigateTo({
      url: '../classList/classList',
    })
  }
})

classList页面:

//classList.wxml
<view wx:for="{{classList}}" wx:key="index" class="classListContainer">
  <view class="className">{{item.className}}</view>
  <view class="inputView">
  <button style="width:40vw" type="primary" class="inputButton" bindtap="chooseExcelFile" data-className="{{item.classNumber}}">导入信息</button>
  </view>
  <view class="outputView">
  <button style="width:40vw" type="primary" class="outputButton" bindtap="outputInfoToExcel" data-className="{{item.classNumber}}">导出信息</button>
  </view>
</view>

//classList.wxss
.classListContainer{
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  padding-right: 20rpx;
  padding-bottom: 40rpx;
}
.inputButton{
  font-size: 30rpx;
  width: 20%;
}
.className{
  font-size: 50rpx;
  padding-right: 20rpx;
}
.outputButton{
  font-size: 30rpx;
  width: 10%;
}

//classList.js
// pages/classList/classList.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    classList: [],
    className: '',
    classNumber: '',
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    wx.cloud.callFunction({
      name: "getClassList"
    }).then(res => {
      console.log("获取所有班级集合成功", res)
      this.setData({
        classList: res.result.data
      })
    }).catch(err => {
      console.log("获取所有班级集合失败", err)
    })
  },

  //1.选择excel文件
  chooseExcelFile(e) {
    let className = e.currentTarget.dataset.classname
    this.setData({
      className: className
    })
    wx.chooseMessageFile({
      count: 1,
      type: "file",
      success: res => {
        let temFile = res.tempFiles[0]
        this.uploadExcelFile(temFile.path)
      }
    })
  },
  //2.上传excel文件到云存储
  uploadExcelFile(path) {
    let that = this
    wx.cloud.uploadFile({
      cloudPath: new Date().getTime() + '.xls',//云存储文件名
      filePath: path,//文件路径
      success: res => {
        console.log("上传成功", res.fileID)
        that.parseExcel(res.fileID)
      },
      fail: err => {
        console.log("上传失败", err)
      }
    })
  },

  //3.解析云存储中的excel文件并上传到云数据库
  parseExcel(fileID) {
    let className = this.data.className
    wx.cloud.callFunction({
      name: "excelOfStudent",
      data: {
        fileID: fileID,
        className: className
      },
      success: res => {
        console.log("解析上传成功", res)
        wx.showToast({
          title: '上传成功',
          icon: "success"
        })
      },
      fail: err => {
        console.log("解析上传失败", err)
        wx.showToast({
          title: '上传失败',
          icon: "error"
        })
      }
    })
  },

  //-----------------------------------------------------------------------------------------
  // //下载班级文件
  // outputInfo(e){
  //   console.log(className)j
  // }
  //从云数据库导出数据到Excel文件
  outputInfoToExcel(e) {
    let className = e.currentTarget.dataset.classname
    //1.获取数据库数据
    wx.cloud.callFunction({
      name: 'getAllClassData',
      data: {
        className: className
      },
      success: res => {
        //let keyNames = []
        if (res.result.data.length == 0) {
          wx.showToast({
            title: '此班级无信息可导出',
            icon: "error"
          })
        } else {
          console.log(res)
          console.log(Object.keys(res.result.data[0]))
          let i = 0
          let keyNameArr = []
          let keyNameMax = 0
          //let keyNames=[]
          let lastKeyNames = []

          // for (i = 0; i < res.result.data.length; i++) {
          //   let keyName = []
          //   keyName = Object.keys(res.result.data[i])

          //   if(keyName.length>keyNameMax){
          //     keyNameMax=keyName.length
          //     keyNameArr=[]
          //     keyNameArr.push(keyName)
          //   }
          // }
          // for(i=0;i<keyNameArr[0].length;i++){
          //   keyNames[i]=keyNameArr[0][i]
          // }

          // console.log("获取成功", res.result.data)
          // console.log(keyNameArr)
          // console.log(keyNames)

          //方法二-------------------------------------------------
          for (var a = 0; a < res.result.data.length; a++) {
            let keyName = []
            keyName = Object.keys(res.result.data[a])
            lastKeyNames = lastKeyNames.concat(keyName)
          }
          console.log(lastKeyNames)
          var keyNames = [lastKeyNames[0]]; //结果数组
          //从第二项开始遍历
          for (var b = 1; b < lastKeyNames.length; b++) {
            //如果当前数组的第i项在当前数组中第一次出现的位置不是i,
            //那么表示第i项是重复的,忽略掉。否则存入结果数组
            if (lastKeyNames.indexOf(lastKeyNames[b]) == b) keyNames.push(lastKeyNames[b]);
          }
          console.log(keyNames)
          this.savaExcel(res.result.data, keyNames)
        }
      },
      fail: err => {
        console.log("获取失败", err)
      }
    })
  },
  //2.把数据保存到excel里,并把excel保存到云存储
  savaExcel(studentData, keyNames) {
    wx.cloud.callFunction({
      name: "classInfoSaveToExcel",
      data: {
        studentData: studentData,
        keyNames: keyNames
      },
      success: res => {
        console.log("保存成功", res)
        this.getFileUrl(res.result.fileID)
      },
      fail: res => {
        console.log("保存失败", res)
      }
    })
  },
  //获取云存储文件下载地址,有效期一天
  getFileUrl(fileID) {
    wx.cloud.getTempFileURL({
      fileList: [fileID],
      success: res => {
        console.log("文件下载链接", res.fileList[0].tempFileURL)
        this.setData({
          fileUrl: res.fileList[0].tempFileURL
        })
      },
      fail: err => {
        console.log(err)
      }
    })
  },
})

(1)新建班级的实现

由于比较简单,接下来直接帖上代码

1.新建班级所有代码如下:

    新建班级的主要作用是在云数据库中实现新建一张以班级编号为名的数据库表。

//newClass.wxml
<form bindsubmit="submit" class="container">
  <view class="class-year">
    <view>班级名称:</view>
    <input class="input" type="text" name="className" data-className=""  value='{{className}}'></input>
  </view>
  <view class="class-name">
    <view>班级编号:</view>
    <input placeholder="支持英文、数字、- 和 _" bindblur="checkClassNumber" class="input" type="text" name="classNumber"
      value='{{classNumber}}'></input>
  </view>
  <button form-type="submit" type="primary" class="button">提交</button>
  <button form-type="reset" type="primary" class="button">重置</button>
</form>

//newClass.js
// pages/newClass/newClass.js
Page({
  data: {
    classNumber: null,
    className: null
  },
 checkClassNumber(e) {
    let classNumber = e.detail.value
    let str = /^\w+$/;
    if (str.test(classNumber)) {
      return true
    } else {
      wx.showToast({
        title: '名称格式有误',
        icon: "error"
      })
      this.setData({
        'classNumber': ''
      })
      return false
    }
  },

  submit(e) {
    console.log(e)
    let classNumber = e.detail.value.classNumber
    let str = /^\w+$/;
    if (str.test(classNumber)) {
      let className = e.detail.value.className
      if (className == '' || className.replace(/\s+/g, '') == '') {
        wx.showToast({
          title: '名称不能为空',
          icon: "error"
        })
        return
      } else if (classNumber) {
        wx.cloud.callFunction({
          name: "addClass",
          data: {
            classNumber: classNumber,
            className: className,
          }
        })
          .then(res => {
            let isExist = res.result
            if (isExist === "exist") {
              wx.showToast({
                title: '班级名称已存在',
                icon: "error"
              })
              this.setData({
                'classNumber': '',
                'className': '',
              })
            } else {
              wx.showToast({
                title: '新建成功',
                icon: "success"
              })
              setTimeout(function () {
                //要延时执行的代码
                wx.navigateBack({
                  delta: 1
                })
              }, 1000)
            }
          }).catch(err => {
            console.log(err)
          })
      } else {
        wx.showToast({
          title: '编号不能为空',
          icon: "error"
        })
        this.setData({
          'classNumber': '',
          'className': '',
        })
      }
      //return true
    } else {
      wx.showToast({
        title: '名称格式有误',
        icon: "error"
      })
      this.setData({
        'classNumber': ''
      })
      return false
    }
  }
})

//newClass.wxss
.button {
  margin: 20rpx 0;
}
.class-name {
  display: flex;
  flex-direction: row;
}
.class-year {
  display: flex;
  flex-direction: row;
}
.class-college {
  display: flex;
  flex-direction: row;
}
.class-major {
  display: flex;
  flex-direction: row;
}
.input{
  border: #dedede solid 1rpx;
}
2.云函数addClass代码实现如下:
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

// 云函数入口函数
exports.main = async (event, context) => {
  let { classNumber, className } = event
  const result = await cloud.database().createCollection(classNumber)
    .then(res => {
      cloud.database().collection('classList').add({
        data: {
          classNumber: classNumber,
          className: className
        }
      })
      console.log("新建班级成功", res)
    })
    .catch(err => {
      console.log("新建班级失败", err)
      return "exist"
    })
  return result
}

    新建班级代码比较简单,结合之前学过的的知识便可实现,接下来也是整合学过的内容,即对云数据库中的班级进行excel文件的导入以及从云数据库导出数据到excel文件中。

(2)上传Excel到云数据库与云数据库下载到excel的实现

!!!记住安装npm install node-xlsx

效果图如下所示:

在这里插入图片描述

获取所有班级列表getClassList云函数代码如下:
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

// 云函数入口函数
exports.main = async (event, context) => {
  return await cloud.database().collection("classList").get({
    success:function(res){
      console.log(res)
      return res;
    },
    fail(err){
      return err;
    }
  });
}
云函数excelOfStudent解析云存储中的excel文件并上传到云数据库,实现代码如下:
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({
  env: '*****************'
})
var xlsx = require('node-xlsx')
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {

  let { fileID,className} = event
  //1.通过fileID下载云存储里的excel文件
  const res = await cloud.downloadFile({
    fileID: fileID,
  })
  const buffer = res.fileContent
  const tasks = [] //用来存储所有的添加数据操作
  //2.解析excel文件里的数据
  var sheets = xlsx.parse(buffer); //获取到所有sheets
  sheets.forEach(function (sheet) {
    console.log(sheet['name']);//sheet
    for (var rowId in sheet['data']) {
      console.log(rowId);
      var row = sheet['data'][rowId]; //第几行数据
      console.log(row)
      let rowName = sheet['data'][0]

      if (rowId > 0 && row) { //第一行是表格标题,从第2行开始读
        jsons={}
        for(i=0;i<rowName.length;i++){
          jsons[rowName[i]] = row[i]
        }
        //3.把解析到的数据存到excelList数据表里
        const promise = db.collection(className)
          .add({
            data:jsons 
          })
        tasks.push(promise)
      }
    }
  });

  // 数据添加完成
  let result = await Promise.all(tasks).then(res => {
    return res
  }).catch(function (err) {
    return err
  })
  return result
}
云函数getAllClassData获取数据库数据,实现代码如下:
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({
  env:'****************'
})
// 云函数入口函数
exports.main = async (event, context) => {
  let className=event.className
  console.log(className)
 return await cloud.database().collection(className).get({
   success:function(res){
     return res;
   },
   fail(err){
     return err;
   }
 });
}
云函数classInfoSaveToExcel把数据保存到excel里,并把excel保存到云存储,实现代码如下:
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
  env: '****************************'
})
var xlsx = require('node-xlsx')
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
  try {
    let { studentData, keyNames } = event
    //1.定义excel表格名
    let tableName = '班级.xlsx'
    //2.定义存储数据的数组
    let alldata = [];
    //let row = ['姓名', '电话', '地址', '性别'];//表属性

    alldata.push(keyNames)
    console.log(keyNames)
    console.log(studentData)
    //3.遍历数组然后存入alldata
    for (let key in studentData) {
      let arr = [];
      for (j = 0; j < keyNames.length; j++) {
        //for (i = 0; i < keyNameArr[j].length; i++) {
        let ccc = ''
        ccc = keyNames[j]
        arr.push(studentData[key][ccc]);
        //}
      }
      console.log(arr)
      alldata.push(arr)
    }

    //4.把数据保存到excel里
    var buffer = await xlsx.build([{
      name: "MySheet",
      data: alldata
    }]);
    //5.把excel文件保存到云存储里
    return await cloud.uploadFile({
      cloudPath: tableName,
      fileContent: buffer, //excel二进制文件
    })
  } catch (e) {
    console.error(e)
    return e
  }
}

最终实现成果如下图所示:
在这里插入图片描述

(3)总结:

    本文章需要注意的是云环境是否存在以及云函数是否安装node依赖,最值得一提的是在云数据库中,若存在多条数据字段个数不统一时或者不相同时,我是将所有的字段进行收集到一个数组里面,而这个数组则作为导出到excel文件中的表头,若某条数据库记录中不存在某字段时,excel表中则为空。还需要学更多东西才能实现自己想要的,路漫漫其修远兮,吾将上下而求索。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值