* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class JSONToCSV {
static setCsvData(obj: unknown): void {
let data = obj.data;
let isShowLabel = typeof obj.showLabel === 'undefined' ? true : obj.showLabel;
let fileName = (obj.fileName || 'UserExport') + '.csv';
let columns = obj.columns || {
title: [],
key: [],
formatter: undefined,
};
let showLabel = typeof isShowLabel === 'undefined' ? true : isShowLabel;
let row = '';
let csv = '';
let key: string;
if (showLabel) {
if (columns.title.length) {
columns.title.map(function (n: unknown) {
row += n + ',';
});
} else {
for (key in data[0]) {
row += key + ',';
}
}
row = row.slice(0, -1);
csv += row + '\r\n';
}
data.map((n: unknown) => {
row = '';
if (columns.key.length) {
row = this.getCsvStr(columns, obj, n, row);
} else {
for (key in n) {
row +=
'"' + (typeof columns.formatter === 'function' ? columns.formatter(key, n[key]) || n[key] : n[key]) + '",';
}
}
row.slice(0, row.length - 1);
csv += row + '\r\n';
});
if (!csv) {
return;
}
this.saveCsvFile(fileName, csv);
}
static getCsvStr(columns: unknown, obj: unknown, n: unknown, row: string): string {
columns.key.map((m: unknown, idx: number) => {
let strItem: unknown = '';
if (obj.exportFormatter && obj.exportFormatter.has(m)) {
strItem = obj.exportFormatter.get(m)?.(n) || n[m];
} else if (obj.formatter && obj.formatter.has(m)) {
strItem = obj.formatter.get(m)?.(n[m]) || n[m];
} else {
strItem = n[m];
}
if (typeof strItem === 'undefined') {
strItem = '';
} else if (typeof strItem === 'object') {
strItem = JSON.stringify(strItem);
strItem = strItem.replaceAll('"', '');
}
if (idx === 0 && typeof n.depthCSV !== 'undefined') {
row +=
'"' +
this.treeDepth(n.depthCSV) +
(typeof columns.formatter === 'function' ? columns.formatter(m, n[m]) || n[m] : strItem) +
'",';
} else {
row += '"' + (typeof columns.formatter === 'function' ? columns.formatter(m, n[m]) || n[m] : strItem) + '",';
}
});
return row;
}
static saveCsvFile(fileName: unknown, csvData: unknown): void {
let alink: unknown = document.createElement('a');
alink.id = 'csvDownloadLink';
alink.href = this.getDownloadUrl(csvData);
document.body.appendChild(alink);
let linkDom: unknown = document.getElementById('csvDownloadLink');
linkDom.setAttribute('download', fileName);
linkDom.click();
document.body.removeChild(linkDom);
}
static getDownloadUrl(csvData: unknown): string | undefined {
let result;
if (window.Blob && window.URL && (window.URL as unknown).createObjectURL) {
result = URL.createObjectURL(
new Blob(['\uFEFF' + csvData], {
type: 'text/csv',
})
);
}
return result;
}
static treeDepth(depth: number): string {
let str = '';
for (let i = 0; i < depth; i++) {
str += ' ';
}
return str;
}
static treeToArr(data: unknown): unknown[] {
const result: Array<unknown> = [];
data.forEach((item: unknown) => {
let depthCSV = 0;
const loop = (data: unknown, depth: unknown): void => {
result.push({ depthCSV: depth, ...data });
let child = data.children;
if (child) {
for (let i = 0; i < child.length; i++) {
loop(child[i], depth + 1);
}
}
};
loop(item, depthCSV);
});
return result;
}
static columnsData(columns: Array<unknown>): {
titleList: unknown[];
ketList: unknown[];
} {
let titleList: Array<unknown> = [];
let ketList: Array<unknown> = [];
columns.forEach((column) => {
let dataIndex = column.getAttribute('data-index');
let columnName = column.getAttribute('title');
if (columnName === '') {
columnName = dataIndex === 'busyTimeStr' ? 'GetBusyTime(ms)' : dataIndex;
}
if (columnName !== ' ') {
titleList.push(columnName);
ketList.push(dataIndex);
}
});
return {
titleList: titleList,
ketList: ketList,
};
}
static async csvExport(dataSource: {
columns: unknown[];
tables: unknown[];
fileName: string;
columnFormatter: Map<string, (value: unknown) => string>;
exportFormatter: Map<string, (value: unknown) => string>;
}): Promise<string> {
return new Promise((resolve) => {
let data: unknown = this.columnsData(dataSource.columns);
let columns = {
title: data.titleList,
key: data.ketList,
};
if (dataSource.tables.length > 0) {
if (Array.isArray(dataSource.tables[0])) {
dataSource.tables.forEach((childArr, childIndex) => {
let resultArr = JSONToCSV.treeToArr(childArr);
JSONToCSV.setCsvData({
data: resultArr,
fileName: `${dataSource.fileName}_${childIndex}`,
columns: columns,
formatter: dataSource.columnFormatter,
});
});
} else {
let resultArr = JSONToCSV.treeToArr(dataSource.tables);
JSONToCSV.setCsvData({
data: resultArr,
fileName: dataSource.fileName,
columns: columns,
formatter: dataSource.columnFormatter,
exportFormatter: dataSource.exportFormatter,
});
}
}
resolve('ok');
});
}
}