目的:因为项目的框架是uniapp,因此在开发小程序的状况下,采用了小程序的云函数来解析excel表格(撸码不易,请笔芯点个赞)。node
云开发的好处:数据库
采用云开发解析excel的步骤:npm
一、填写小程序appid,选择创建云开发模板,点击建立按钮。小程序
二、建立成功后会进入这样一个界面,而后咱们就能够点击云开发按钮,进入开通阶段,暂时能够选择免费版本的。后端
一、在cloudfunctions的目录下右键点击选择新建Node.js云函数,新建一个云函数微信小程序
二、这样咱们就建立好了一个excel云函数了。数组
三、在excel的目录下右键点击选择外部终端窗口,输入npm install node-xlsx 安装依赖。安装完成后,看到node-xlsx的版本号就算安装成功了。服务器
首先咱们先配置miniprogram目录下的app.js的环境变量,代码以下:微信
//app.jsApp({ onLaunch: function () {if (!wx.cloud) { console.error('请使用 2.2.3 或以上的基础库以使用云能力') } else { wx.cloud.init({// env 参数说明:// env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪一个云环境的资源// 此处请填入环境 ID, 环境 ID 可打开云控制台查看// 如不填则使用默认环境(第一个建立的环境)env: 'xxxxxxxxxxxxxx', //该环境变量可从云平台中找到traceUser: true, }) }this.globalData = {} } })复制代码
配置完成后编写云函数的步骤以下:app
一、编写excel的index.js。贴上代码以下:
//index.jsconst cloud = require('wx-server-sdk') cloud.init({env: "xxxxxxxxxxxxxxx"}) //该env环境变量可从云平台中找到var xlsx = require('node-xlsx'); //引用node-xlsx依赖const db = cloud.database() //实例化db库exports.main = async (event, context) => { let {fileID} = event //1,经过fileID下载云存储里的excel文件const res = await cloud.downloadFile({fileID: fileID}) const buffer = res.fileContent const all_excel_data = [] //用来存储全部的excel数据//2,解析excel文件里的数据var sheets = xlsx.parse(buffer); //获取到全部sheets,由于表格可能会有多张表 sheets.forEach(function(sheet) {//这里粗暴的用了else if 来处理对应的表名的内容,并处理相应的字段//(这里大家能够按照大家的表格内容,本身作相应的处理)if (sheet['name'] == "LoRa网关") { for (var rowId in sheet['data']) { var row = sheet['data'][rowId]; if (rowId > 1 && row.length) { all_excel_data.push({ addr: row[0], type: row[1], id: row[2], name: row[3], sheetName:"LoRa网关" }) } } }else if (sheet['name'] == "LoRa终端") { for (var rowId in sheet['data']) { var row = sheet['data'][rowId]; if (rowId > 1 && row.length) { all_excel_data.push({ type: 0, addr: row[0], id: row[1], sheetName:"LoRa终端" }) } } }else if (sheet['name'] == "监测设备") { for (var rowId in sheet['data']) { var row = sheet['data'][rowId]; if (rowId > 1 && row.length) { all_excel_data.push({ type: 1, addr: row[0], id: row[1], sheetName:"监测设备" }) } } }else if (sheet['name'] == "无线路由") { for (var rowId in sheet['data']) { var row = sheet['data'][rowId]; if (rowId > 1 && row.length) { all_excel_data.push({ targetDeviceId: row[0], addr1: row[1], addr2: row[2], addr3: row[3], addr4: row[4], addr5: row[5], addr6: row[6], addr7: row[7], addr8: row[8], sheetName:"无线路由" }) } } }else if (sheet['name'] == "测点") { for (var rowId in sheet['data']) { var row = sheet['data'][rowId]; if (rowId > 1 && row.length) { all_excel_data.push({ name: row[0], id: row[1], dataType: row[2], readWriteType: row[3], addr: row[4], regAddr: row[5], uploadInterval: row[6], collectByteCount: row[7], gain: row[8], offset: row[9], uploadDataType: row[10], sheetName:"测点" }) } } }else if (sheet['name'] == "条件上报") { for (var rowId in sheet['data']) { var row = sheet['data'][rowId]; if (rowId > 1 && row.length) { all_excel_data.push({ id: row[0], condition: row[1], num1: row[2], num2: row[3], sheetName:"条件上报" }) } } } });// 一块儿添加全部数据var result = await db.collection('users').add({ //这里的 users 字段必定要和云平台的数据哭的集合名称保持一致data: all_excel_data }).then(res => { return res }).catch(err => { return err }) return result }复制代码
二、编写好excel的index.js云函数后,发现其中有个问题,就是每次拿到excel的内容丢到数据库时,若是不清空之前的数据库,数据库数据就会不断的增长或者被覆盖,因此咱们又新建了一个云函数deleData,建立方法跟建立excel函数同样,但云函数deleData的index.js代码以下:
const cloud = require('wx-server-sdk') cloud.init({env: "xxxxxxxxxxxxxxx"}) //该env环境变量可从云平台中找到const db = cloud.database()exports.main = async(event, context) => { let {type,_id} = event try {if (type == 'all') { const _ = db.command return await db.collection('users').where({_id: _.exists(true) //只要_id字段存在,就删除 }).remove() } else { return await db.collection('users').where({_id: _id }).remove() } } catch (e) {console.error(e) } }复制代码
三、编写好全部的云函数后,能够右键点击恰好已经搞好的两个云函数deleData和excel选择上传并部署,部署成功后,之后若是要来修改对应的index.js的业务逻辑的时候,把修改好的index.js增量上传就好。
一、先初始化云开发的环境
wx.cloud.init({env: 'xxxxxxxxxxxxx'});var db = wx.cloud.database();复制代码
一、使用wx.chooseMessageFile来选择微信对话列表中的文件,wx.chooseMessageFile上传文件,wx.cloud.callFunction调用咱们前面所建立的云函数excel并成功返回解析后的数据,完整代码以下:
export default { data() { return { fileName: '', //文件名 }; }, onLoad() { wx.cloud.init({ env: 'xxxxxxxxxxxxxxx' }); db = wx.cloud.database(); }, methods: { //选择excel表格chooseFile() { wx.chooseMessageFile({ count: 1, type: 'file', success: res => { if (res.tempFiles[0].name.indexOf('.xlsx') == -1) { this.showToast('选择的文件不是excel文件,请从新选择!'); return; } this.fileName = res.tempFiles[0].name; let path = res.tempFiles[0].path; this.uploadExcel(path); }, fail: err => { console.log(err); } }); }, // 上传excel表格到云存储uploadExcel(path) { wx.cloud.uploadFile({ cloudPath: new Date().getTime() + '.xls', filePath: path, success: async res => { console.log('上传成功', res.fileID); //先获取数据库全部的数据长度let getData = await db .collection('users') .where({}) .count(); //每隔20条去删除数据,直到清空数据库for (let i = 0; i < getData.total; i += 20) { this.getListIndexSkip(i).then(async res => { //清空数据库await wx.cloud.callFunction({ name: 'deledata', data: { type: 'all', _id: res._id }, success: res => { console.log(res); }, fail: err => { console.log('删除失败', err); } }); }); }; setTimeout(() => { this.parseF(res.fileID); }, 50) }, fail: err => { this.showToast('解析excel失败!'); console.log('上传失败', err); } }); }, //解析文件parseF(fileID) { wx.cloud.callFunction({ name: 'excel', data: { fileID: fileID }, success: async res => { console.log('解析并上传成功', res); let getData = await db .collection('users') .where({}) .count(); console.log("长度:" + getData.total); let list = []; for (let i = 0; i < getData.total; i += 20) { this.getListIndexSkip(i).then(res => { list = list.concat(res); if (list.length == getData.total) { console.log(list); //list为解析返回来的数组this.showToast('解析excel成功!'); } }); } }, fail: err => { console.log('解析失败', err); this.showToast('解析excel失败!'); } }); }, //单次查询函数getListIndexSkip(skip) { return new Promise((resolve, reject) => { let statusList = []; let selectPromise; if (skip > 0) { selectPromise = db .collection('users') .where({}) .skip(skip) .get(); } else { selectPromise = db .collection('users') .where({}) .get(); } selectPromise .then(res => { resolve(res.data); }) .catch(e => { console.error(e); reject('查询失败!'); }); }); }, //弹框显示showToast(val) { uni.showToast({ title: val, icon: 'none' }); }, } };复制代码
二、以上的例子返回的结果跟云平台的数据库彻底一致,效果截图以下:
返回来的数据,这里是以数组的形式来展现