Я пытаюсь сохранить данные в json, чтобы преуспеть в файле .xlsx. Json выглядит так (с изменением имен значений, это просто пример):
{"hum_in":[{"ts":1646034284215,"value":"22"},{"ts":1646033983313,"value":"22"}]}
Я попытался преобразовать и загрузить, используя этот код:
const EXCEL_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
const EXCEL_EXTENSION = '.xlsx';
function downloadAsExcel(data) {
const worksheet = XLSX.utils.json_to_sheet(data);
const workbook = {
Sheets: {
'data': worksheet
},
SheetNames: ['data']
};
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
console.info(excelBuffer);
saveAsExcel(excelBuffer);
}
function saveAsExcel(buffer) {
const data = new Blob([buffer], { type: EXCEL_TYPE });
saveAs(data, "Export_" + new Date().getTime() + EXCEL_EXTENSION);
}
а затем вызывая это так:
downloadAsExcel(json);
Он вернул ошибку:
TypeError: r.forEach is not a function
at rb (xlsx.full.min.js:23:18346)
at Object.tb [as json_to_sheet] (xlsx.full.min.js:23:19000)
at downloadAsExcel (app.js:233:34)
at app.js:112:25
Кто-нибудь знает, что пошло не так?
Функция json_to_sheet принимает массив, тогда как ваш аргумент data
является объектом. Вместо этого передайте ему свойство hum_in
, чтобы настроить таргетинг на внутренний массив данных:
const worksheet = XLSX.utils.json_to_sheet(data.hum_in);
Вот более полный пример, включающий поддержку нескольких ключей в объекте данных:
const data = {"hum_in":[
{"ts":1646034284215,"value":"22"},
{"ts":1646033983313,"value":"22"}
]};
function generateAsExcel(data) {
try {
const workbook = XLSX.utils.book_new();
for (let key in data) {
const worksheet = XLSX.utils.json_to_sheet(data[key]);
XLSX.utils.book_append_sheet(workbook, worksheet, key);
}
let res = XLSX.write(workbook, { type: "array" });
console.info(`${res.byteLength} bytes generated`);
} catch (err) {
console.info("Error:", err);
}
}
document.getElementById("gen").addEventListener("click",
() => generateAsExcel(data));
<script type = "text/javascript" src = "//cdn.jsdelivr.net/npm/xlsx/dist/xlsx.full.min.js"></script>
<button id = "gen">Generate</button>
Чтобы объединить все ключи data
в набор данных для создания одного рабочего листа, вы можете использовать что-то вроде этого:
const data = {
"hum_in":[ {"ts":1646034284215,"value":"22"}, {"ts":1646033983313,"value":"22"} ],
"wind_dir":[ {"ts":1646034284215,"value":"123"}, {"ts":1646033983313,"value":"125"} ]
};
let merged = Object.keys(data).reduce((merged, key) => {
for (record of data[key]) { merged.push(Object.assign({ key }, record)); }
return merged;
}, []);
console.info(merged);
Пример с добавленной поддержкой нескольких ключей, каждый ключ в объекте data
будет экспортирован на новый лист
Спасибо, работает хорошо! Можно ли разместить все ключи только на одном листе?
Добавлен дополнительный пример объединения наборов данных.
Большое спасибо! Есть ли какая-то документация на все это? Я пытался найти его, но, возможно, я не так искал.
Документы SheetJS доступны здесь, там много примеров
Я не могу добавить свойство hum_in, потому что это свойство всегда меняется в зависимости от того, что клиент хочет экспортировать (один раз это hum_in, в следующий раз это wind_dir и так далее). Есть ли способ сделать это без точного свойства?