
excel表格式如上,前面14行的数据不要,最后一行不要,只要中间标题以及内容,多个表合并成一个excel:如下

上部分:上次ecxel文件,上传完之后,点击合并按钮开始合并
下部分:打印日志,包括:错误日志,成功日志



桌面就会出现一个以当前日期命名的excel合并文件。
当然,如果你传入的格式不对,则会提示你格式错误,如下:

目录结构:

该项目的主要难点就是一个,如何前后端通信,
1)在background.js 使用ipcMain监听通信
如下:
将文件拖到此处,或点击此处
点击合并
上面的文件中使用:ipcRenderer.send(“uploadChooseExcel”, fileList); 发送文件列表。
import { ipcMain } from "electron";
const fs = require('fs');
// node path模块
const path = require('path');
const xlsx = require('node-xlsx');
import log from 'electron-log';
import { formatDate } from '@/utils';
// 收集所有的文件路径
var lists = []; // 储存所有数据
var oPath = __dirname.slice(0, __dirname.indexOf('dist_electron'))
log.transports.file.resolvePath = () => path.resolve(`${oPath}/log/${formatDate(new Date(), 'yyyy-MM-dd')}.log`);
log.transports.console.level = 'silly';
export const getExcel = (webContents) => {
ipcMain.on("uploadChooseExcel", function (event, arg) {
fileDisplay(arg)
});
};
const fileDisplay = files => {
//根据文件路径读取文件,返回文件列表
log.info(`读取配置中...
`)
files.forEach((filename, index) => {
//获取当前文件的绝对路径
// fs.stat(path)执行后,会将stats类的实例返回给其回调函数。
log.info(`读取文件${filename}
`)
fs.stat(filename, (eror, stats) => {
if (eror) return log.error(`Error:(spec)${eror}
`);
// 是否是文件
const isFile = stats.isFile();
// 是否是文件夹
const isDir = stats.isDirectory();
if (isFile) {
if (filename.includes('.xls') || filename.includes('xlsx')) { // excel文件
//读取Excel文件
var data = xlsx.parse(filename);
var list1 = data[0].data
let excelHeader = [
'保单号',
'批单号',
'类别',
'期次',
'险种',
'客户',
'业务员',
'个团',
'新旧车',
'合作网点',
'含税保费',
'净保费',
'出单时间',
'保费收入',
'原比例%',
'本次比例%',
'本次手续费/经纪费(人民币)',
'手续费增值税',
'合计支付含增值税金额'
]
let configPath = path.join(oPath, `/config.txt`)
fs.exists(configPath, (exists) => {
if (!exists) {
var filePath = path.join(oPath, `/config.txt`); // 创建txt
fs.writeFileSync(filePath, excelHeader);//
createMerge(list1, excelHeader, index, files, filename)
return
}
fs.readFile(configPath, (err, data) => {
var string = data.toString()
var arr = [];
if (string) {
arr = string.split(',').map(v => v.trim());
}
createMerge(list1, arr.length == 0 ? excelHeader : arr, index, files, filename)
})
})
} else {
log.error(`${filename}:不是excel文件
`)
}
}
// 如果是文件夹
if (isDir) fileDisplay(filename);
})
});
}
function getNowMonths() {
let timeOne = new Date();
let year = timeOne.getFullYear();
let month = timeOne.getMonth() + 1;
let day = timeOne.getDate();
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
const NOW_MONTHS_AGO = `${year}-${month}-${day}`;
return NOW_MONTHS_AGO;
}
function createMerge(list, excelHeader, index, files, filename) {
let sum = 0, isTrue = false, lineNum = 0;
for (let i = 0; i < list.length; i++) {
if (isTrue) break
if (excelHeader.length != list[i].length) {
continue;
}
for (let j = 0; j < list[i].length; j++) {
if (excelHeader[j] == list[i][j]) {
lineNum = i
isTrue = true
sum++;
}
}
}
if (sum != excelHeader.length) {
return log.error(`${filename}:表头与规定的格式不匹配
`);
}
var tempList = list.slice(lineNum + 1, list.length - 1);
lists = lists.concat(tempList)
if (index == files.length - 1) { // 全部读取完
try {
lists.unshift(excelHeader)
const options = {}
var desktop = `${require('os').homedir()}\\Desktop`
var buffer = xlsx.build([{ name: 'sheet1', data: lists }], options);
var date = getNowMonths()
var filePath = path.join(desktop, `/${date}.xlsx`); // 存储路劲和文件名
fs.writeFileSync(filePath, buffer, { 'flag': 'w' });//
log.info(`合并文件成功,文件储存在桌面,路径为:${require('os').homedir()}\\Desktop\\${date}.xlsx
`)
} catch (err) {
if (err.errno == -4082) {
log.error(`上传失败,上一个合并的文件正在打开,请关闭之后再重新上传待合并文件
`)
}
}
lists = [];
isTrue = false
}
}
大概主要的就是这些,其实还是有很多优化的,后续会优化一下。
噢,对了,还有一个设置表头的功能


log.error(上传失败,上一个合并的文件正在打开,请关闭之后再重新上传待合并文件 )
}
}
lists = [];
isTrue = false
}
}
大概主要的就是这些,其实还是有很多优化的,后续会优化一下。
#### 四、后续
噢,对了,还有一个设置表头的功能
[外链图片转存中...(img-dRD6tXcl-1662538336371)]
[外链图片转存中...(img-yOUqn6PP-1662538336371)]
该功能就是excel默认表头,可以手动设置,一次设置,后面就按照设置的来,其实就是设置了一个txt文件,从该文件进行读取而已。