SheetJS 使用json_to_sheet指定标题顺序

SheetJS specify header order with json_to_sheet

提问人:Prithvi Emmanuel Machado 提问时间:12/15/2022 最后编辑:Robin MackenziePrithvi Emmanuel Machado 更新时间:12/18/2022 访问量:1625

问:

我在 angular 中使用 SheetJS 将 json 导出为 .xlsx 文件。作为参考,json 可以如下所示:

[{
   "ID": "E111",
   "Name": "John",
   "LastLogin": "2022-02-12"
},
{
   "ID": "E112",
   "Name": "Jake",
   "Score": 22
   "LastLogin": "2022-02-12"
}]

注意:对象的键是未知的,可能会有所不同。唯一已知的键是 和 。IDLastLogin

我正在使用以下函数导出

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 如下所示

enter image description here

无论对象如何,我都想成为最后一列。有没有办法实现这一目标?我对此很陌生,所以任何帮助都是值得赞赏的。LastLogin

javascript json excel angularjs sheetjs

评论


答:

0赞 Robin Mackenzie 12/18/2022 #1

SheetJS 在这里的行为是从第一行开始采用 Excel 数据的列标题顺序,然后在遇到新的对象键时,在末尾添加匹配的行标题。

要控制此行为以使输出格式化为所需的方式,可以在调用 之前处理输入 json。XLSX.utils.json_to_sheet

定义此函数:

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
  • ensure 是数组的最后一个元素LastLogin
  • 为每个输入对象创建一个新对象,如果原始数据没有属性(例如),则值为Scoreundefined

现在,在您的方法中,只需在第一行之前进行以下调整:exportAsExcelFile

const newJson = restructureObjectForSheet(json);
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(newJson );