亿级电商微信小程序流量实战系列之如何使用云开发导出订单信息至excel文件?

使用场景

使用了云开发的数据库时,客户的订单信息在云数据库里,需要导出信息打印快递单号发货,这个时候就需要本篇文章的技术了。
其实,导出订单信息只是导出云数据库字段信息的一个分支,要从云数据库里导出其他数据集的数据按照本篇文章的操作同理。

解决思路

  1. 采用小程序端触发云函数执行导出订单代码段
  2. 云函数中读取所有的待发货订单信息,并拦截掉已经停发的订单区域,不进行载入表格
  3. 组织好xlsx文件中每一行要存放的数据内容
  4. 调用第三方JS包,将上述组织好的数据注入buffer变量内存中
  5. 调用cloud.uploadFile()上传函数,将数据上传至指定路径的云存储中
  6. 向前端返回整个导出函数对每个数据进行的执行情况

开发准备

  1. 微信开发者工具
  2. 云数据库里留有客户订单信息的数据集
  3. 创建相应的云函数,并配置好云函数的JS第三方包

开发过程

小程序端

触发云函数执行,并将返回的云文件fileID传值给下载函数获取下载链接

  /**
   * 通过云函数导出订单
   * //把数据保存到excel里,并把excel保存到云存储
   * 参数:导出订单的查询条件
   */
  savaExcel() {
    let that = this

    //显示提示
    wx.showLoading({
      title: '正在导出订单',
      icon: 'loading'
    })

    //调用云函数  导出订单
    wx.cloud.callFunction({
      name: "excel",
      data: {
        action: 'exportOrders'
      },
      success(res) {
        // console.log("保存成功", res)

        //调用获取云文件临时下载链接函数,传入数据包含生成的云文件fileID    //返回的云端数据包括被拦截的订单,但是将 链接压入数据头部,故下标为0
        that.getFileUrl(res)

      },
      fail(res) {
        // console.log("保存失败", res)
        wx.showToast({
          icon: 'none',  //不填默认为success 只能显示8个汉字
          title: '导出订单失败,请稍后重试。错误信息:' + res,
          duration: 6000
        })
      }
    })
  },

获取云文件下载地址,并在成功回调的函数里调用复制文本函数。注意:获取到的下载链接时效只有24小时。24小时后需要重新获取公网下载地址。

  /**
   * //获取云存储文件下载地址,这个地址有效期一天
   * 传入上个函数 返回的云数据
   */
  getFileUrl(cloudResult) {
    let that = this,
      fileID = cloudResult.result[0].fileID;  //返回的云端数据包括被拦截的订单,但是将 链接压入数据头部,故下标为0

    wx.cloud.getTempFileURL({
      fileList: [fileID],
      success: res => {
        // get temp file URL
        // console.log("文件下载链接", res.fileList[0].tempFileURL)
        //隐藏提示
        wx.hideLoading();

        that.setData({
          fileUrl: res.fileList[0].tempFileURL,
          historyorders: cloudResult.result   //为了优化视觉体验,所以到这里才传入相关的值
        })

        that.copyFileUrl()  //链接生成成功调用复制按钮

      },
      fail: err => {
        // handle error
      }
    })
  },

复制下载链接地址
为什么要复制?因为在小程序里直接下载下来打开后只能看看,没有办法发给指定的人,并且下载的文件是在微信定义的临时文件夹里,受10M大小的限制的。在这种情况下,只好将复制到的链接拿到浏览器里去打开,并下载文件。

  /**
   * //复制excel文件下载链接
   */
  copyFileUrl() {
    let that = this
    wx.setClipboardData({
      data: that.data.fileUrl,
      success(res) {
        wx.getClipboardData({
          success(res) {
            // console.log("复制成功", res.data) // data
            wx.showToast({
              title: '链接复制成功',
            })
          }
        })
      }
    })
  },

云函数端

初始化云函数环境。注意:声明云数据库全局操作变量,要在云函数初始化cloud之后才可以进行声明,否则会报错。

// 云函数入口文件
const cloud = require('wx-server-sdk')

const app = require('tcb-admin-node');

//操作excel用的类库
const xlsx = require('node-xlsx');

// 初始化 cloud
cloud.init({
  env: process.env.Env  //云函数环境切换 process.env.配置的变量名
})

//操作云数据库使用的变量  要在初始化 cloud 之后再进行声明
const db = cloud.database();
const _ = db.command  //数据库的command命令
const $ = _.aggregate   //聚合使用声明符

/**
 * 触发相应动作
 * action 要触发运行的代码片段//
 * formId 用户触发能发 模板的Id
 */
// 云函数入口函数
exports.main = async (event, context) => {

  //输出操作者的日志到控制台上
  console.log('操作者openid=> ' + event.userInfo.openId)

  switch (event.action) {

    case 'exportOrders': {  //导出订单
      return exportOrders(event)
    } 

  } //switch 大括号结束

生成excel文件函数。对于待发货的订单,在保存数据的时候将某个字段设为标记字段,通过查询相应标记值获取待发订单数据即可。注意:云函数中单次数据获取的上限是100,如果待发货超出这个数量,要进行分批次获取。以下demo中没有写分批次获取的代码,需要请自行修改。 拦截停发区域的方法,其实就是字符串判断,对于符合拦截字符串进行拦截即可。

/**
 * 导出订单
 * 所查询的 待发货条件 与批量导出订单 所查询的条件要保持一致
 * 
 * 前端页面 客户个人的 待发货查询条件也要与此保持一致 出了客户自己的openid查询条件外 都要保持一致
 * courierNumber: _.or(_.eq(null),_.eq('')),     //字段不存在的为待发货  客服修改过后可能导致 该字段成为'' 故增加这个选择 与批量发货条件保持一致
 * 前端页面的位置是 pages/tabBar/queryorder/queryorder
 * 
 * 
 * var province = ["广东", "北京", "浙江", "福建", "湖北", "上海", "江苏", "天津", "河北", "山西", "内蒙古", "辽宁", "吉林", "黑龙江", "安徽", "江西", "山东", "河南", "湖南", "广西", "海南", "重庆", "四川", "贵州", "云南", "西藏", "陕西", "甘肃", "青海", "宁夏", "新疆", "台湾", "香港", "澳门"];
 */
async function exportOrders(event) {

  try {

    const tasks = [] //用来存储所有要返回的数据
    let stopAreaTemp = await db.collection('control').where({
      _id: 'fissionCode'
    }).field({
      stopArea:true //只返回 停发区域字段数值
    }).get()
    // console.log(stopAreaTemp.data[0].stopArea)  //获取停发区域数组
    // return
    const stopArea = stopAreaTemp.data[0].stopArea

    //0,按照查询条件,读取订单数据
    let temp = await db.collection('Shopping').where(
         queryConditions_steamQuantity
      )
      .orderBy('specifications', 'desc').get()

    let orderdata = temp.data

    //0.5,构造导出时间 以便文件命名  Date.now()是时间戳
    let curDate = new Date();
    let time = `${curDate.getFullYear()}${curDate.getMonth() +1}${curDate.getDate()}${curDate.getHours() + 8}-${curDate.getMinutes()}-${curDate.getSeconds()}`;
    /构造明文下单日期代码结束///

    //1,定义excel文件名     商品名+导出的时间.xlsx
    let fileName = `微信小程序-${time}.xlsx`
    //2,定义存储数据的
    let alldata = []
    let row = ['业务单号', '收件人', '收件人电话', '收件人地址', '备注', '客户留言', '物流公司(请填写物流公司名称,没填则为百世快递)','百熟内部留言','订单日期']  //表头属性  即表格第一行的 名称  ,备注即为 商品名+商品规格
    alldata.push(row)

    //从第二行开始写入数据
    for (let key in orderdata) {    //注意要与数据表里的字段名字相同字相同  key 从0 到orderdata 的长度。orderdata[key].quantity 单条数据里的 购买数量 用它循环几次

      ///*拦截停发区域代码块 *****///
      let judge = await stopAreaJudge(orderdata[key].address, stopArea)    //进入判断拦截地址的函数 被拦截则返回1
      if (judge==1){
            //拦截输出的代码块///
              let arr = []    //清空arr,重新拼凑一行数据
              arr.push(orderdata[key]._id)  //业务单号
              arr.push(orderdata[key].consignee)
              arr.push(orderdata[key].tel)
              arr.push(orderdata[key].address)
              arr.push(orderdata[key].specifications)  //备注   商品名+商品规格  productSpecifications
              arr.push(orderdata[key].message)  //客户留言
              arr.push('')  //发快递的占位空格
              arr.push(orderdata[key].orderRemarks)  //百熟内部留言
              arr.push(orderdata[key].time)  //订单日期
              tasks.push(arr)   //一行数据完结了,写入缓存  将拦截的订单写入一会儿要返回的变量里
        continue //继续开始下次循环
      } 
      ///*********************** */

  正常发货时的 组织数据
      for (let i=0;i< orderdata[key].quantity;i++){   //数量比较多的,就多循环几次,这样快递按行打单的就没有问题了
        let arr = []    //清空arr,重新拼凑一行数据
        arr.push(orderdata[key]._id+'-'+i)  //只有一件的时候 业务单号-0
        arr.push(orderdata[key].consignee)
        arr.push(orderdata[key].tel)
        arr.push(orderdata[key].address)
        arr.push(orderdata[key].specifications)  //备注   商品名+商品规格  productSpecifications
        arr.push(orderdata[key].message)  //客户留言
        arr.push('')  //发快递的占位空格
        arr.push(orderdata[key].orderRemarks)  //百熟内部留言
        arr.push(orderdata[key].time)  //订单日期
        alldata.push(arr)   //一行数据完结了,写入缓存
      }
      
    } //for (let key in orderdata) {}结束

    //3,把数据保存到excel里
    var buffer = await xlsx.build([{
      name: "mySheetName",
      data: alldata
    }])

    //4,把excel文件保存到云存储里,并返回 云端文件路径
    const promise = await cloud.uploadFile({
      cloudPath: '商品订单/' + fileName,   //文件夹不存在则会自动创建
      fileContent: buffer,  //excel二进制文件
    })
    tasks.unshift(promise) //从头部压入云端路径

    //格式化一下 要返回的数据  云端文件路径 与 停发区域的订单信息
    // 等待所有数据添加完成
    let result = await Promise.all(tasks).then(res => {
      return res
    }).catch(function (err) {
      return '导出订单,返回任务过程发生错误' + err
    })
    // console.log(result)
    return result
    


  } catch (e) {
    console.error('导出订单错误信息:'+e)
    return e
  }

}
***********导出订单************** */ 

是否停发区域字符串判断函数,注意stopArea数组变量是由上一个函数传递来的。

/**
 * 包裹一个函数方法,拿来判断是否停发区域
 * 传入参数 地址,停发区变量数组
 * 返回参数 有停发区域时 1 
 */
async function stopAreaJudge(address,stopArea) {

  ///* 判断有没有 停发区域的订单  **
  for (var i = 0; i < stopArea.length; i++) {
    if (address.substr(0, 9).indexOf(stopArea[i].slice(0, 2)) > -1) {
      return 1
    }
  }

}

总结

本篇文章介绍了整个订单信息导出实现的过程,其实不仅仅是导出订单信息,只要是在云数据库里的数据,按照本篇文章介绍的技术方法,全部可以导出。不过,要注意导出时候的极限值,云函数中读取的数量是100上限,超出的话要进行分批次读取。
感谢CSDN,感谢原力计划,本来不打算写这篇文章的,看见另一篇被选入热门了,就把这一篇补充一下了。本篇文章是《亿级电商微信小程序流量,如何优雅的使用云开发进行订单发货?》的前序,有了订单信息才能进行发货嘛。
欢迎大家收藏关注,我将不定期分享微信小程序云开发中遇到的问题以及技巧分享,让大家可以避免重复走我走过的坑。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白天到处飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值