1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciexport class JSONToCSV {
17fb726d48Sopenharmony_ci  static setCsvData(obj: unknown): void {
18fb726d48Sopenharmony_ci    // @ts-ignore
19fb726d48Sopenharmony_ci    let data = obj.data;
20fb726d48Sopenharmony_ci    // @ts-ignore
21fb726d48Sopenharmony_ci    let isShowLabel = typeof obj.showLabel === 'undefined' ? true : obj.showLabel;
22fb726d48Sopenharmony_ci    // @ts-ignore
23fb726d48Sopenharmony_ci    let fileName = (obj.fileName || 'UserExport') + '.csv';
24fb726d48Sopenharmony_ci    // @ts-ignore
25fb726d48Sopenharmony_ci    let columns = obj.columns || {
26fb726d48Sopenharmony_ci      title: [],
27fb726d48Sopenharmony_ci      key: [],
28fb726d48Sopenharmony_ci      formatter: undefined,
29fb726d48Sopenharmony_ci    };
30fb726d48Sopenharmony_ci    let showLabel = typeof isShowLabel === 'undefined' ? true : isShowLabel;
31fb726d48Sopenharmony_ci    let row = '';
32fb726d48Sopenharmony_ci    let csv = '';
33fb726d48Sopenharmony_ci    let key: string;
34fb726d48Sopenharmony_ci    // 如果要现实表头文字
35fb726d48Sopenharmony_ci    if (showLabel) {
36fb726d48Sopenharmony_ci      // 如果有传入自定义的表头文字
37fb726d48Sopenharmony_ci      if (columns.title.length) {
38fb726d48Sopenharmony_ci        columns.title.map(function (n: unknown) {
39fb726d48Sopenharmony_ci          row += n + ',';
40fb726d48Sopenharmony_ci        });
41fb726d48Sopenharmony_ci      } else {
42fb726d48Sopenharmony_ci        // 如果没有,就直接取数据第一条的对象的属性
43fb726d48Sopenharmony_ci        for (key in data[0]) {
44fb726d48Sopenharmony_ci          row += key + ',';
45fb726d48Sopenharmony_ci        }
46fb726d48Sopenharmony_ci      }
47fb726d48Sopenharmony_ci      row = row.slice(0, -1);
48fb726d48Sopenharmony_ci      csv += row + '\r\n';
49fb726d48Sopenharmony_ci    }
50fb726d48Sopenharmony_ci    // 具体的数据处理
51fb726d48Sopenharmony_ci    data.map((n: unknown) => {
52fb726d48Sopenharmony_ci      row = '';
53fb726d48Sopenharmony_ci      // 如果存在自定义key值
54fb726d48Sopenharmony_ci      if (columns.key.length) {
55fb726d48Sopenharmony_ci        row = this.getCsvStr(columns, obj, n, row);
56fb726d48Sopenharmony_ci      } else {
57fb726d48Sopenharmony_ci        // @ts-ignore
58fb726d48Sopenharmony_ci        for (key in n) {
59fb726d48Sopenharmony_ci          row +=
60fb726d48Sopenharmony_ci            // @ts-ignore
61fb726d48Sopenharmony_ci            '"' + (typeof columns.formatter === 'function' ? columns.formatter(key, n[key]) || n[key] : n[key]) + '",';
62fb726d48Sopenharmony_ci        }
63fb726d48Sopenharmony_ci      }
64fb726d48Sopenharmony_ci      row.slice(0, row.length - 1); // 删除最后一个,
65fb726d48Sopenharmony_ci      csv += row + '\r\n'; // 添加换行符号
66fb726d48Sopenharmony_ci    });
67fb726d48Sopenharmony_ci    if (!csv) {
68fb726d48Sopenharmony_ci      return;
69fb726d48Sopenharmony_ci    }
70fb726d48Sopenharmony_ci    this.saveCsvFile(fileName, csv);
71fb726d48Sopenharmony_ci  }
72fb726d48Sopenharmony_ci
73fb726d48Sopenharmony_ci  static getCsvStr(columns: unknown, obj: unknown, n: unknown, row: string): string {
74fb726d48Sopenharmony_ci    // @ts-ignore
75fb726d48Sopenharmony_ci    columns.key.map((m: unknown, idx: number) => {
76fb726d48Sopenharmony_ci      let strItem: unknown = '';
77fb726d48Sopenharmony_ci      // @ts-ignore
78fb726d48Sopenharmony_ci      if (obj.exportFormatter && obj.exportFormatter.has(m)) {
79fb726d48Sopenharmony_ci        // @ts-ignore
80fb726d48Sopenharmony_ci        strItem = obj.exportFormatter.get(m)?.(n) || n[m];
81fb726d48Sopenharmony_ci        // @ts-ignore
82fb726d48Sopenharmony_ci      } else if (obj.formatter && obj.formatter.has(m)) {
83fb726d48Sopenharmony_ci        // @ts-ignore
84fb726d48Sopenharmony_ci        strItem = obj.formatter.get(m)?.(n[m]) || n[m];
85fb726d48Sopenharmony_ci      } else {
86fb726d48Sopenharmony_ci        // @ts-ignore
87fb726d48Sopenharmony_ci        strItem = n[m];
88fb726d48Sopenharmony_ci      }
89fb726d48Sopenharmony_ci      if (typeof strItem === 'undefined') {
90fb726d48Sopenharmony_ci        strItem = '';
91fb726d48Sopenharmony_ci      } else if (typeof strItem === 'object') {
92fb726d48Sopenharmony_ci        strItem = JSON.stringify(strItem);
93fb726d48Sopenharmony_ci        // @ts-ignore
94fb726d48Sopenharmony_ci        strItem = strItem.replaceAll('"', '');
95fb726d48Sopenharmony_ci      }
96fb726d48Sopenharmony_ci      // @ts-ignore
97fb726d48Sopenharmony_ci      if (idx === 0 && typeof n.depthCSV !== 'undefined') {
98fb726d48Sopenharmony_ci        row +=
99fb726d48Sopenharmony_ci          '"' +
100fb726d48Sopenharmony_ci          // @ts-ignore
101fb726d48Sopenharmony_ci          this.treeDepth(n.depthCSV) +
102fb726d48Sopenharmony_ci          // @ts-ignore
103fb726d48Sopenharmony_ci          (typeof columns.formatter === 'function' ? columns.formatter(m, n[m]) || n[m] : strItem) +
104fb726d48Sopenharmony_ci          '",';
105fb726d48Sopenharmony_ci      } else {
106fb726d48Sopenharmony_ci        // @ts-ignore
107fb726d48Sopenharmony_ci        row += '"' + (typeof columns.formatter === 'function' ? columns.formatter(m, n[m]) || n[m] : strItem) + '",';
108fb726d48Sopenharmony_ci      }
109fb726d48Sopenharmony_ci    });
110fb726d48Sopenharmony_ci    return row;
111fb726d48Sopenharmony_ci  }
112fb726d48Sopenharmony_ci
113fb726d48Sopenharmony_ci  static saveCsvFile(fileName: unknown, csvData: unknown): void {
114fb726d48Sopenharmony_ci    let alink: unknown = document.createElement('a');
115fb726d48Sopenharmony_ci    // @ts-ignore
116fb726d48Sopenharmony_ci    alink.id = 'csvDownloadLink';
117fb726d48Sopenharmony_ci    // @ts-ignore
118fb726d48Sopenharmony_ci    alink.href = this.getDownloadUrl(csvData);
119fb726d48Sopenharmony_ci    // @ts-ignore
120fb726d48Sopenharmony_ci    document.body.appendChild(alink);
121fb726d48Sopenharmony_ci    let linkDom: unknown = document.getElementById('csvDownloadLink');
122fb726d48Sopenharmony_ci    // @ts-ignore
123fb726d48Sopenharmony_ci    linkDom.setAttribute('download', fileName);
124fb726d48Sopenharmony_ci    // @ts-ignore
125fb726d48Sopenharmony_ci    linkDom.click();
126fb726d48Sopenharmony_ci    // @ts-ignore
127fb726d48Sopenharmony_ci    document.body.removeChild(linkDom);
128fb726d48Sopenharmony_ci    // @ts-ignore
129fb726d48Sopenharmony_ci
130fb726d48Sopenharmony_ci  }
131fb726d48Sopenharmony_ci
132fb726d48Sopenharmony_ci  static getDownloadUrl(csvData: unknown): string | undefined {
133fb726d48Sopenharmony_ci    let result;
134fb726d48Sopenharmony_ci    // @ts-ignore
135fb726d48Sopenharmony_ci    if (window.Blob && window.URL && (window.URL as unknown).createObjectURL) {
136fb726d48Sopenharmony_ci      result = URL.createObjectURL(
137fb726d48Sopenharmony_ci        new Blob(['\uFEFF' + csvData], {
138fb726d48Sopenharmony_ci          type: 'text/csv',
139fb726d48Sopenharmony_ci        })
140fb726d48Sopenharmony_ci      );
141fb726d48Sopenharmony_ci    }
142fb726d48Sopenharmony_ci    return result;
143fb726d48Sopenharmony_ci  }
144fb726d48Sopenharmony_ci
145fb726d48Sopenharmony_ci  static treeDepth(depth: number): string {
146fb726d48Sopenharmony_ci    let str = '';
147fb726d48Sopenharmony_ci    for (let i = 0; i < depth; i++) {
148fb726d48Sopenharmony_ci      str += '    ';
149fb726d48Sopenharmony_ci    }
150fb726d48Sopenharmony_ci    return str;
151fb726d48Sopenharmony_ci  }
152fb726d48Sopenharmony_ci
153fb726d48Sopenharmony_ci  static treeToArr(data: unknown): unknown[] {
154fb726d48Sopenharmony_ci    const result: Array<unknown> = [];
155fb726d48Sopenharmony_ci    // @ts-ignore
156fb726d48Sopenharmony_ci    data.forEach((item: unknown) => {
157fb726d48Sopenharmony_ci      let depthCSV = 0;
158fb726d48Sopenharmony_ci      const loop = (data: unknown, depth: unknown): void => {
159fb726d48Sopenharmony_ci        // @ts-ignore
160fb726d48Sopenharmony_ci        result.push({ depthCSV: depth, ...data });
161fb726d48Sopenharmony_ci        // @ts-ignore
162fb726d48Sopenharmony_ci        let child = data.children;
163fb726d48Sopenharmony_ci        if (child) {
164fb726d48Sopenharmony_ci          for (let i = 0; i < child.length; i++) {
165fb726d48Sopenharmony_ci            // @ts-ignore
166fb726d48Sopenharmony_ci            loop(child[i], depth + 1);
167fb726d48Sopenharmony_ci          }
168fb726d48Sopenharmony_ci        }
169fb726d48Sopenharmony_ci      };
170fb726d48Sopenharmony_ci      loop(item, depthCSV);
171fb726d48Sopenharmony_ci    });
172fb726d48Sopenharmony_ci    return result;
173fb726d48Sopenharmony_ci  }
174fb726d48Sopenharmony_ci
175fb726d48Sopenharmony_ci  static columnsData(columns: Array<unknown>): {
176fb726d48Sopenharmony_ci    titleList: unknown[];
177fb726d48Sopenharmony_ci    ketList: unknown[];
178fb726d48Sopenharmony_ci  } {
179fb726d48Sopenharmony_ci    let titleList: Array<unknown> = [];
180fb726d48Sopenharmony_ci    let ketList: Array<unknown> = [];
181fb726d48Sopenharmony_ci    columns.forEach((column) => {
182fb726d48Sopenharmony_ci      // @ts-ignore
183fb726d48Sopenharmony_ci      let dataIndex = column.getAttribute('data-index');
184fb726d48Sopenharmony_ci      // @ts-ignore
185fb726d48Sopenharmony_ci      let columnName = column.getAttribute('title');
186fb726d48Sopenharmony_ci      if (columnName === '') {
187fb726d48Sopenharmony_ci        columnName = dataIndex === 'busyTimeStr' ? 'GetBusyTime(ms)' : dataIndex;
188fb726d48Sopenharmony_ci      }
189fb726d48Sopenharmony_ci      if (columnName !== '  ') {
190fb726d48Sopenharmony_ci        titleList.push(columnName);
191fb726d48Sopenharmony_ci        ketList.push(dataIndex);
192fb726d48Sopenharmony_ci      }
193fb726d48Sopenharmony_ci    });
194fb726d48Sopenharmony_ci    return {
195fb726d48Sopenharmony_ci      titleList: titleList,
196fb726d48Sopenharmony_ci      ketList: ketList,
197fb726d48Sopenharmony_ci    };
198fb726d48Sopenharmony_ci  }
199fb726d48Sopenharmony_ci
200fb726d48Sopenharmony_ci  static async csvExport(dataSource: {
201fb726d48Sopenharmony_ci    columns: unknown[];
202fb726d48Sopenharmony_ci    tables: unknown[];
203fb726d48Sopenharmony_ci    fileName: string;
204fb726d48Sopenharmony_ci    columnFormatter: Map<string, (value: unknown) => string>;
205fb726d48Sopenharmony_ci    exportFormatter: Map<string, (value: unknown) => string>;
206fb726d48Sopenharmony_ci  }): Promise<string> {
207fb726d48Sopenharmony_ci    return new Promise((resolve) => {
208fb726d48Sopenharmony_ci      let data: unknown = this.columnsData(dataSource.columns);
209fb726d48Sopenharmony_ci      let columns = {
210fb726d48Sopenharmony_ci        // @ts-ignore
211fb726d48Sopenharmony_ci        title: data.titleList,
212fb726d48Sopenharmony_ci        // @ts-ignore
213fb726d48Sopenharmony_ci        key: data.ketList,
214fb726d48Sopenharmony_ci      };
215fb726d48Sopenharmony_ci      if (dataSource.tables.length > 0) {
216fb726d48Sopenharmony_ci        if (Array.isArray(dataSource.tables[0])) {
217fb726d48Sopenharmony_ci          dataSource.tables.forEach((childArr, childIndex) => {
218fb726d48Sopenharmony_ci            let resultArr = JSONToCSV.treeToArr(childArr);
219fb726d48Sopenharmony_ci            JSONToCSV.setCsvData({
220fb726d48Sopenharmony_ci              data: resultArr,
221fb726d48Sopenharmony_ci              fileName: `${dataSource.fileName}_${childIndex}`,
222fb726d48Sopenharmony_ci              columns: columns,
223fb726d48Sopenharmony_ci              formatter: dataSource.columnFormatter,
224fb726d48Sopenharmony_ci            });
225fb726d48Sopenharmony_ci          });
226fb726d48Sopenharmony_ci        } else {
227fb726d48Sopenharmony_ci          let resultArr = JSONToCSV.treeToArr(dataSource.tables);
228fb726d48Sopenharmony_ci          JSONToCSV.setCsvData({
229fb726d48Sopenharmony_ci            data: resultArr,
230fb726d48Sopenharmony_ci            fileName: dataSource.fileName,
231fb726d48Sopenharmony_ci            columns: columns,
232fb726d48Sopenharmony_ci            formatter: dataSource.columnFormatter,
233fb726d48Sopenharmony_ci            exportFormatter: dataSource.exportFormatter,
234fb726d48Sopenharmony_ci          });
235fb726d48Sopenharmony_ci        }
236fb726d48Sopenharmony_ci      }
237fb726d48Sopenharmony_ci      resolve('ok');
238fb726d48Sopenharmony_ci    });
239fb726d48Sopenharmony_ci  }
240fb726d48Sopenharmony_ci}
241