我在 Angular 中使用 SheetJS 将 json 导出为 .xlsx 文件。作为参考,json 可能如下:
[{
"ID": "E111",
"Name": "John",
"LastLogin": "2022-02-12"
},
{
"ID": "E112",
"Name": "Jake",
"Score": 22
"LastLogin": "2022-02-12"
}]
注意:对象的键是未知的,并且可能会有所不同。唯一已知的键是
ID
和 LastLogin
。
我正在使用以下函数来导出
public exportAsExcelFile(json: any[], excelFileName: string): void {
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(json);
console.log('worksheet',worksheet);
const workbook: XLSX.WorkBook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] };
const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
this.saveAsExcelFile(excelBuffer, excelFileName);
}
private saveAsExcelFile(buffer: any, fileName: string): void {
const data: Blob = new Blob([buffer], {
type: EXCEL_TYPE
});
FileSaver.saveAs(data, fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION);
}
生成的 Excel 看起来像这样
无论对象是什么,我都希望
LastLogin
成为最后一列。有办法实现这一点吗?我对此很陌生,因此非常感谢任何帮助。
这里 SheetJS 的行为是从第一行获取 Excel 数据的列标题的顺序,然后当遇到新的对象键时,将匹配的行标题添加到末尾。
要控制此行为以使输出按照您想要的方式格式化,您可以在调用
XLSX.utils.json_to_sheet
之前处理输入 json。
定义这个函数:
function restructureObjectForSheet(obj) {
// for each object in the array put the keys in a new array
// flatten that array
// there will be duplicate names which can be removed with Set
// turn it back into an array
const uniqKeys = Array.from(new Set(obj.map(o => Object.keys(o)).flat()));
// remove LastLogin from this array
// then put LastLogin at the end of the array
const endKey = "LastLogin";
const rowHeaders = uniqKeys.filter(k => k !== endKey).concat(endKey);
// process the original data into a new array
// first entry will define row headers in Excel sheet
const newData = obj.map(o => {
return rowHeaders.reduce((a, c) => {a[c] = o[c] ; return a}, {});
});
return newData;
}
我已经对代码进行了注释,但基本功能是:
json
变量)LastLogin
是数组的最后一个元素Score
),则值为 undefined
现在,在您的
exportAsExcelFile
方法中,只需在第一行之前进行此调整:
const newJson = restructureObjectForSheet(json);
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(newJson );
这将帮助您重新排列标题并重命名它们:
只需使用map函数将typescript对象重组为具有所需标题的数组-
const jsonFromTsObjectArray = this.myTsObjArray.map(value=>({
'My Header 1': value.prop2,
'My Header 2': value.prop1
}));
然后将新创建的对象使用到XLSX-
const ws:XLSX.workSheet = XLSX.utils.json_to_sheet(jsonFromTsObjectArray);