Mit*_*hal 5 javascript npm js-xlsx angular sheetjs
我有一个包含 id 和数据的多个标签的数组:
[
{
"id": "tagID1",
"error": { "code": 0, "success": true },
"data": [
[1604395417575, 108, 3],
[1604395421453, 879, 3]
]
},
{
"id": "tagID2",
"error": {"code": 0, "success": true},
"data": [
[1604395417575, 508, 3],
[1604395421453, 179, 3]
]
}
]
Run Code Online (Sandbox Code Playgroud)
我想使用NPM 的xlsx包将此数据转换为 Excel 电子表格。
注:1604395417575 是时间戳,608 是值,3 是质量。
我想按以下格式在 Excel 工作表中显示
| Timestamp | tagID1 value | tagID1 quality | tagID2 value | tagID2 quality|
| -------- | -------------- | -------- ------| -------------| ------------- |
| 1604395417575| 108 | 3 | 508 | 3 |
| 1604395421453| 879 | 3 | 179 | 3 |
Run Code Online (Sandbox Code Playgroud)
更新工作表格式
|----------------------------------------------------------
| Timestamp | TagID-1 | TagID-2 |
| | ----------------------------------------
| | value | quality | value | quality |
|----------------------------------------------------------
| 1604395417575| 108 | 3 | 508 | 3 |
| 1604395421453| 879 | 3 | 179 | 3 |
Run Code Online (Sandbox Code Playgroud)
我是 XLSX(又名 SheetJS)新手 - 我该怎么做?
下面的代码遵循的过程是:
id通过将每个对象的和data属性排列成一个长列表来转换数据order末尾的数字id1tagID1Timestamp届时对该新数组进行排序order- 如果您的数据已经按该顺序排序,则可能没有必要tagIDN quality和 对tagIDN valueXLSX.utils.aoa_to_sheet0工作代码:
const XLSX = require("xlsx");
// input data
const input_data = [
{
"id": "tagID1",
"error": { "code": 0, "success": true },
"data": [
[1604395417575, 108, 3],
[1604395421453, 879, 3]
]
},
{
"id": "tagID2",
"error": {"code": 0, "success": true},
"data": [
[1604395417575, 508, 3],
[1604395421453, 179, 3]
]
}
];
// data transforms
// 1st transform - get long array of objects
const prep = input_data.map(obj => {
return obj.data.map(arr => {
return {
"TimeStamp": arr[0],
"id": obj.id,
"order": +obj.id.substr(5, obj.id.length - 5),
"quality": arr[1],
"value": arr[2]
}
});
}).flat();
// sort by timestamp asc, order asc
prep.sort((a, b) => a.TimeStamp - b.TimeStamp || a.order - b.order);
// headers
const headers = ["Timestamp"].concat(
[...new Set(prep.map(obj => obj.id))]
.map(id => [`${id} quality`, `${id} value`])
.flat()
);
// organise the data - in wide format
const ws_data = [...new Set(prep.map(obj => obj.TimeStamp))]
.map(ts => {
const objByTimestamp = prep.filter(obj => obj.TimeStamp === ts);
let arr = [ts];
objByTimestamp.forEach(obj => arr = arr.concat([obj.quality, obj.value]));
return arr;
});
// prepend the headers
ws_data.unshift(headers);
// to Excel
// new workbook
const wb = XLSX.utils.book_new();
// create sheet with array-of-arrays to sheet method
const ws = XLSX.utils.aoa_to_sheet(ws_data);
// assign sheet to workbook
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
// set column A as text
const range = XLSX.utils.decode_range(ws['!ref']);
console.log(range);
for (let i = range.s.r; i <= range.e.r; i++) {
const ref = XLSX.utils.encode_cell({r: i , c: 0});
console.log(ref);
ws[ref].z = "0";
}
// save workbook
XLSX.writeFile(wb, "C:\\Users\\Robin\\Desktop\\so.xlsx", {});
Run Code Online (Sandbox Code Playgroud)
Excel 输出:
要在第一行上有带有合并单元格的双标题(对于标签 ID) - 请参阅更新:
const XLSX = require("xlsx");
// input data
const input_data = [
{
"id": "tagID1",
"error": { "code": 0, "success": true },
"data": [
[1604395417575, 108, 3],
[1604395421453, 879, 3]
]
},
{
"id": "tagID2",
"error": {"code": 0, "success": true},
"data": [
[1604395417575, 508, 3],
[1604395421453, 179, 3]
]
}
];
// data transforms
// 1st transform - get long array of objects
const prep = input_data.map(obj => {
return obj.data.map(arr => {
return {
"TimeStamp": arr[0],
"id": obj.id,
"order": +obj.id.substr(5, obj.id.length - 5),
"quality": arr[1],
"value": arr[2]
}
});
}).flat();
// sort by timestamp asc, order asc
prep.sort((a, b) => a.TimeStamp - b.TimeStamp || a.order - b.order);
// headers
// const headers = ["Timestamp"].concat(
// [...new Set(prep.map(obj => obj.id))]
// .map(id => [`${id} quality`, `${id} value`])
// .flat()
// );
const ids = [...new Set(prep.map(obj => obj.id))];
const headers1 = [""].concat(ids.map(id => Array(2).fill(id)).flat());
const headers2 = ["Timestamp"].concat(ids.map(id => Array(["quality", "value"])).flat()).flat();
// organise the data - in wide format
const ws_data = [...new Set(prep.map(obj => obj.TimeStamp))]
.map(ts => {
const objByTimestamp = prep.filter(obj => obj.TimeStamp === ts);
let arr = [ts];
objByTimestamp.forEach(obj => arr = arr.concat([obj.quality, obj.value]));
return arr;
});
// prepend the headers
ws_data.unshift(headers2);
ws_data.unshift(headers1);
// to Excel
// new workbook
const wb = XLSX.utils.book_new();
// create sheet with array-of-arrays to sheet method
const ws = XLSX.utils.aoa_to_sheet(ws_data);
// assign sheet to workbook
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
// set column A as text
const range = XLSX.utils.decode_range(ws['!ref']);
for (let i = range.s.r; i <= range.e.r; i++) {
const ref = XLSX.utils.encode_cell({r: i , c: 0});
ws[ref].z = "0";
}
// assign merges to sheet
// /sf/ask/3746148241/
const merges = ids.reduce((acc, curr, idx) => {
acc.push({
s: {r: 0, c: 1 + (2 *idx)},
e: {r: 0, c: 1 + (2 *idx) + 1}
});
return acc;
}, []);
ws["!merges"] = merges;
// save workbook
XLSX.writeFile(wb, "C:\\Users\\Robin\\Desktop\\so.xlsx", {});
Run Code Online (Sandbox Code Playgroud)
Excel 输出:
方法按照这篇文章。