SheetJS 使用 json_to_sheet 指定标题顺序

问题描述 投票:0回答:2

我在 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
成为最后一列。有办法实现这一点吗?我对此很陌生,因此非常感谢任何帮助。

javascript json excel angularjs sheetjs
2个回答
0
投票

这里 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 );

0
投票

这将帮助您重新排列标题并重命名它们:

只需使用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);
© www.soinside.com 2019 - 2024. All rights reserved.