koa导入导出excel

导出excel文件流

因为使用了koa的model,所以我这里封装了一个通用的方法来导出

导出方法

option:

  • modelName: koa中的模型名
  • attributes: 需要导出的模型字段
  • where: 筛选条件(这里是根据了projectCode项目代码来筛选)
  • titleArr: attributes对应的中文解释
  • fileName: 导出文件的名称
  • isTemplete: 是否为导入模板,如果传1,将会返回仅包含attributes栏和tittleArr栏的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* export specified model data to excel
* @param options modelName:string,attributes:Array,where:object,titleArr:Arr,fileName:string
*/
export function export2Excel(options: any) {
let { modelName, attributes, where, titleArr, fileName, isTemplete } = options;
// 去除假值
attributes = attributes.filter(d=>d)
titleArr = titleArr.filter(d=>d)

return models[modelName]
.findAll({
attributes,
where,
})
.then((results) => {
// 模板的话置空
results = isTemplete ? [] : JSON.parse(JSON.stringify(results));
if (results) {
let datas = isTemplete? [attributes]: [underscore.keys(results[0])];
datas.push(titleArr);
for (let i in results) {
let result = results[i];
var value = underscore.values(result);
value[0] = parseInt(i) + parseInt('1');
datas.push(value);
}
var buffer = xlsx.build([{ name: fileName, data: datas }]);
return buffer;
} else {
return {
result: 1,
msg: 'Failed',
};
}
});
}

控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 导出
* param:
* comm_code
* isTemplete: 1为获取模板
*/
deviceExport: async (ctx, next) => {
let { projectCode , isTemplete } = ctx.request.query;
let options = {
modelName: 'Device',
attributes: [
isTemplete?null:'id',
isTemplete?null:'device_guid',
'device_type',
'addr',
'ip',
'name',
],
where: projectCode ? { projectCode } : null,
titleArr: [
isTemplete?null:'序号',
isTemplete?null:'设备唯一码',
'设备类型',
'设备地址',
'IP',
'设备名',
],
fileName: 'devices',
isTemplete
};
let exportData = await export2Excel(options);
ctx.set('Content-Type', 'application/vnd.openxmlformats');
ctx.set('Content-Disposition', `attachment; filename=device.xlsx`);
ctx.body = exportData;
},

导入

  1. 导入相关包

    1
    2
    3
    npm install koa-multer node-xlsx xlsx
    // 如果是typescript,还需要
    npm install @types/koa-multer @types/node-xlsx
  2. 文件中导入依赖

    1
    2
    import multer from 'koa-multer';
    import XLSX from 'xlsx';
  3. 配置文件存储

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import fs from 'fs'
    import path from 'path'
    if(!fs.existsSync(path.resolve('./public'))) fs.mkdirSync(path.resolve('./public'))

    let storage = multer.diskStorage({
    // 文件保存路径
    destination: function (req, file, cb) {
    cb(null, './public');
    },
    // 修改文件名
    filename: function (req, file, cb) {
    var fileFormat = file.originalname.split('.');
    cb(null, Date.now() + '.' + fileFormat[fileFormat.length - 1]);
    },
    });
  4. 加载配置

    1
    2
    //加载配置
    let upload = multer({ storage: storage })
  5. 在路由中配置上传路由

    1. 有多种上传方式,但是single就够了
    2. ‘file’是上传的字段名
    1
    router.post('/device/import',upload.single('file'),device_controller.import);
  6. 控制器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import XLSX from 'xlsx';

    /**
    * @version 1.0
    * @author yiqing
    * @description 导入设备
    */
    import:async(ctx,next)=>{
    let file = ctx.req.file.filename;
    const xlsxFile = path.resolve('./public', file);
    async function readExcel() {
    return new Promise((resolve, reject) => {
    // read file
    let rawfile = fs.readFileSync(xlsxFile);
    file = XLSX.read(rawfile);
    // get json array
    let j_data = XLSX.utils.sheet_to_json(file.Sheets[file.SheetNames[0]]);
    // 移除自己添加的中文解释
    j_data.shift()
    resolve(j_data);
    });
    }
    let data:any = await readExcel();
    // 删除文件
    fs.unlinkSync(xlsxFile)
    }