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