需求描述
通过代码比对现文件与原文件的异常情况,并通过文件导出。
实现逻辑
- 将上传文件转为
Array
格式 - 进行数据比对
- 将处理好的文件展示在表格上,或者导出
文件上传
<script>
import XLSX from 'xlsx'
export default {
name: 'CompareExcel',
data () {
return {
originData: [], // 原始数据
compareData: [], // 对比数据
}
},
methods: {
onChangeFile (file, type) {
const fileReader = new FileReader()
fileReader.onload = (e) => {
const data = new Uint8Array(e.target.result)
const { SheetNames, Sheets } = XLSX.read(data, { type: 'array' })
const workSheet = Sheets[SheetNames[0]]
const sheetRows = XLSX.utils.sheet_to_json(workSheet)
if (type === 'origin') {
const originTitle = sheetRows[0]
const originTitleKeys = Object.keys(originTitle)
const originTitleValues = Object.values(originTitle)
sheetRows.forEach((item, index) => {
if (index !== 0) {
let newItem = {}
originTitleValues.forEach((key, keyIndex) => {
newItem[key] = item[originTitleKeys[keyIndex]] || null
})
this.originData.push(newItem)
}
})
} else {
this.compareData = sheetRows
}
}
fileReader.readAsArrayBuffer(file.raw)
},
}
}
</script>
这里提供了两种文件的处理格式,如果是基本的Excel,在
XLSX.utils.sheet_to_json
将其转为json文件后,直接存储就可以了,但是在线文档下载为Excel后,数据格式并不是键值对,因此需要通过处理,将其变成[{ name:value }]的这种格式。
textExcel: [
{ 表格: '', _empty1: '序号', _empty2: '姓名', _empty3: '年龄', _empty4: '性别', _empty5: '备注' },
{ 表格: '', _empty1: '1', _empty2: '张三', _empty3: '18', _empty4: '男', _empty5: '测试1' },
{ 表格: '', _empty1: '2', _empty2: '李四', _empty3: '20', _empty4: '女', _empty5: '测试2' },
{ 表格: '', _empty1: '3', _empty2: '王五', _empty3: '22', _empty4: '男', _empty5: '测试3' },
]
数据比对
/** 对比 */
onCompare () {
this.resultData = []
console.log(this.originData, this.compareData, 'this.originData, this.compareData')
// 通过姓名进行对比
this.compareData.forEach(item => {
const findItem = this.originData.find(originItem => originItem['姓名'] === item['姓名'])
if (findItem) {
let errorMsg = []
const compareKey = Object.keys(item)
compareKey.forEach(key => {
if (findItem[key] !== item[key]) {
errorMsg.push(`${key}不同,原数据为${findItem[key]},对比数据为${item[key]}`)
}
})
// 如果有不同数据
if (errorMsg.length > 0) {
const finalItem = { origin: findItem, compare: item, error: errorMsg }
this.resultData.push(finalItem)
}
}
// else {
// const finalItem = { origin: null, compare: item, error: ['未找到对应数据'] }
// this.resultData.push(finalItem)
// }
})
// 处理报错数据
const addErrorData = this.resultData.map(x => ({ ...x.compare, error: x.error.join(';') }))
const header = Object.keys(addErrorData[0])
addErrorData.forEach(item => {
let newItem = []
header.forEach(key => {
newItem.push(item[key])
})
this.showData.push(newItem)
})
console.log(addErrorData, 'addErrorData', header,this.showData)
// 导出时,数据为定义好的全部数据格式
// 表头 = ["id", "姓名", "年龄"]
// 内容 = [ [1, "张三", 18], [2, "李四", 20 ] ]
exportJsonToExcel({
multiHeader: [],
header: header,
data: this.showData,
filename: `对比结果`
})
},
数据比对的逻辑是,首先确定一个key值作为比对的点,然后找到两条匹配的数据,然后再通过
Object.keys
寻找name,将相同name的value值进行比对,如果不一致,增加一条error信息输出,这里比对可以使用更细节的方法,比如大小写忽略等等,按实际业务情况去做。
最后的addErrorData
就是处理好的数据,可以直接在页面上输出,也可以再导出为Excel。
文件导出
addErrorData.forEach(item => {
let newItem = []
header.forEach(key => {
newItem.push(item[key])
})
this.showData.push(newItem)
})
console.log(addErrorData, 'addErrorData', header,this.showData)
// 导出时,数据为定义好的全部数据格式
// 表头 = ["id", "姓名", "年龄"]
// 内容 = [ [1, "张三", 18], [2, "李四", 20 ] ]
exportJsonToExcel({
multiHeader: [],
header: header,
data: this.showData,
filename: `对比结果`
})
使用
exportJsonToExcel
导出文件,这里的data如注释所示,数据必须是像Excel内部一样形成每行的数据数组,才能成功导出。因此先要