云环境1.0.51
小程序的云开发功能为我们带来了很大的方便,于是就打算研究一下如何在云函数中拉取数据,之后生成excel到云存储中,过程中踩了些坑,这里分享给大家,希望能有所帮助。
首先了解一个node端生成excel的库excel-export
虽然已经许久未更新了,但是目前还没有什么太大的问题,所以在他的基础上进行开发,并且上手也比较容易
主要用法
- 引入
let nodeExcel = require('excel-export');
- 创建配置对象
let conf = {
stylesXmlFile, // 约束文件(不然生成的excel打开会报一些问题)
cols, // 可理解为表头 [{ caption: 'columnName', type: 'string' }], 这里出于方便,type为string,具体可移步其文档查看
rows, // 可以理解为填充的数据 ['wechat', 'mp']
}
- 创建流对象
let result = nodeExcel.execute(conf)
// 普通node后端可以直接使用 res.end(result, 'binary'); 进行下载,要记得添加相应的头,其文档里也有说明
// 最终可以使用 Buffer.from(result.toString(), 'binary') 转换为一个Buffer对象
嵌入云开发
大致的思路就是 [拉取数据] -> [生成excel流对象] -> [上传到云存储中] -> [返回该fileID]
几个踩坑点
- 读入文件要使用
path.resolve(__dirname, 'xxx')
- 得到excel流对象 使用
Buffer.from(result.toString(), 'binary')
再配合cloud.uploadFile
- 生成时conf要配置
stylesXmlFile
,不然打开文件总有个提示,很不爽!styles.xml
这个文件可以在node_modules/excel-export/example/styles.xml
找到。 - 数据和表头最好是对应的,数据也可以存在空值
云函数目录结构
- testDownload
- |- index.js
- |- styles.xml
- |- package.json
- |- package-lock.json
- |- node_modules (在开发工具中应该是不显示的)
package.json中的依赖
"dependencies": {
"excel-export": "^0.5.1",
"wx-server-sdk": "latest"
}
index.js文件代码
// 云函数入口文件
const cloud = require('wx-server-sdk')
const nodeExcel = require('excel-export')
const fs = require('fs')
const path = require('path')
cloud.init({
env: "xxxx" // 你的环境
})
const db = cloud.database()
// 生成分数项并且下载对应的excel
exports.main = async (event, context) => {
let collectionId = '123666' // 模拟的集合名
let openId = 'sda6248daa888764' // 模拟openid
let confParams = ['姓名', '学号', '签到时间'] // 模拟表头
let jsonData = []
// 获取数据
await db.collection(collectionId).get().then(res => {
jsonData = res.data
})
// 转换成excel流数据
let conf = {
stylesXmlFile: path.resolve(__dirname, 'styles.xml'),
name: 'sheet',
cols: confParams.map(param => {
return { caption: param, type: 'string' }
}),
rows: jsonToArray(jsonData)
}
let result = nodeExcel.execute(conf) // result为excel二进制数据流
// 上传到云存储
return await cloud.uploadFile({
cloudPath: `download/sheet${openId}.xlsx`, // excel文件名称及路径,即云存储中的路径
fileContent: Buffer.from(result.toString(), 'binary'),
})
// json对象转换成数组填充
function jsonToArray (arrData) {
let arr = new Array()
arrData.forEach(item => {
let itemArray = new Array()
for (let key in item) {
if (key === '_id' || key === '_openid') { continue }
itemArray.push(item[key])
}
arr.push(itemArray)
})
return arr
}
}
触发云函数,可以看到云存储中有了刚刚生成的文件
数据库中的数据,
由于表头都是一样的,所以这边的key可以适当的简化,但是要注意数据库中拉取数据顺序的问题
最终生成的excel
谢谢分享!另请教如何读、写本地或已经上传在云储存的EXCEL文件?