关于对外部Excel文件的处理并实现数据添加

前言

今天的总结来自于修修整整两天才完成的一个问题。先说需求,在一个页面上,想要实现点击“批量导入”按钮,将外部Excel文件导入,并根据文件中数据的id字段,在数据模型中查询到这些id对应的数据,并添加到另外一个数据模型中。(这样即使Excel文件中其他字段错误,只要id值正确,我们即可将数据添加成功)

这样听起来似乎有些模糊,但可以将需求拆分成几个步骤单独处理。

实现

1.Excel数据转换

首先是最简单的,将导入的Excel文件转换为json数据。

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

export default function ({ event, data }) {
//点击“批量导入”按钮后调起上传文件的input标签导入事件
document.querySelector('.weda-upload-file-pc__input-box input').click()
// 读取本地excel文件
function readWorkbookFromLocalFile(file, callback) {
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
var workbook = XLSX.read(data, { type: 'binary' });
if (callback) callback(workbook);
};
reader.readAsBinaryString(file);
}
function readWorkbook(workbook) {
var sheetNames = workbook.SheetNames; // 工作表名称集合
var worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheet
var excelData = XLSX.utils.sheet_to_json(worksheet);

// 输出导入的excel信息
console.log('excelData', excelData);
var oeArr = []
for (var i = 0; i < excelData.length; i++) {
var obj = new Object
obj.id = excelData[i].id
obj.oe = excelData[i].oe
obj.num=excelData[i].jianshu
oeArr.push(obj)
}
if(oeArr.length>0){
$w.page.dataset.state.oeList=oeArr
}

console.log('oeArr', oeArr)
return oeArr

}
// 增加上传文件事件
document.querySelector('.weda-upload-file-pc__input-box input').addEventListener('change', function (e) {
console.log('input值改变了')
console.log('e.target.files', e.target.files[0])
var files = e.target.files;
if (files.length === 0) {
return;
}
var f = files[0];
//此处支持的格式可以自己设置
if (!/\.xls$/g.test(f.name) && !/\.xlsx$/g.test(f.name)) {
alert('仅支持读取xls格式或者xlsx格式');
return;
}
readWorkbookFromLocalFile(f, function (workbook) {
readWorkbook(workbook);
});
});
}

这里需要注意的是Excel文件中的字段最好是英文,便于我们获取处理后的json数据。

获取到json数据后,存储给当前页面中的数组变量,这里写为List

2.添加数据

​ 在第一步给List变量赋值成功后,调用我们自定义的用于添加数据的方法addList,将List变量作为参数传入。

​ addList方法如下,主要实现思路是新建一个数据和对象变量,用于存储筛选后的数据。对于List数据,我们先根据List中的某个字段,调用微搭内置的查询方法,去数据源(这里称为A表)中查询这个字段对应的数据,然后只提取部分字段信息,存储到新对象中,并push到新数组中;循环完毕,这个数组中就包含了我们需要的数据。

这里还涉及到一个地方,因为上面我们查询的A表有个字段和其他表是关联关系(其他表称为B表),所以我们还需要对当前数组数据做进一步处理。调用微搭的新增方法,将数组arr传入,会返回给我们一个id字段,这个字段就是整个arr数据关联B表的唯一标识。这时候再将id字段添加给arr数据的每个对象作为属性,最后将arr添加进我们想要的C表

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
export default async function ({ event, data }) {
console.log('传入的oeList-----data.target', data.target);
var arr = [];
for (var i = 0; i < data.target.length; i++) {
var obj = {
jtcx: '',
oe_number: '',
part_name: '',
pjzt: '',
part_quantity: 1

}
const result = await app.cloud.callModel({
name: 'oe_mabiao_sv6nvje',
methodName: 'wedaGetItem',
params: {
"where": [
{
"key": "oe",
"rel": "eq",
"val": data.target[i].oe
}
]
},
});
// result是包含配件信息的对象
console.log('result1', result)
// obj.glscjh = result._id
obj.jtcx = result.car_brand + '' + result.car_group
obj.oe_number = result.oe
obj.part_name = result.part_name
obj.pjzt = '待拣货'

if (data.target[i].num > 1) {
for (var j = 0; j < data.target[i].num; j++) {
arr.push(obj)
console.log('push了'+j+'次')
}
}else if(data.target[i].num==1){
arr.push(obj)
}
console.log('arr', arr)
}
// 关联
const result2=await app.cloud.callModel({
name: 'scjh_jmuj401',
methodName: 'wedaCreate',
params: {
records: arr
},
});
console.log('result2',result2)
arr.forEach(item=>{
Object.assign(item,{glscjh:result2._id})
})
console.log('添加完生产计划的arr',arr)
//添加多条
const result3 = await app.cloud.callModel({
name: 'jhqd_8saf1y2',
methodName: 'wedaBatchCreate',
params: {
records: arr
},
});

}