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 setDataConver(obj: any) { 18 let that = this; 19 let bw = this.browser(); 20 if (bw['ie'] < 9) return; 21 let data = obj['data'], 22 Show = typeof obj['showLabel'] === 'undefined' ? true : obj['showLabel'], 23 fileName = (obj['fileName'] || 'UserExport') + '.csv', 24 columns = obj['columns'] || { 25 title: [], 26 key: [], 27 formatter: undefined, 28 }; 29 let ShowLabel = typeof Show === 'undefined' ? true : Show; 30 let row = '', 31 CSV = '', 32 key; 33 // 如果要现实表头文字 34 if (ShowLabel) { 35 // 如果有传入自定义的表头文字 36 if (columns.title.length) { 37 columns.title.map(function (n: any) { 38 row += n + ','; 39 }); 40 } else { 41 // 如果没有,就直接取数据第一条的对象的属性 42 for (key in data[0]) row += key + ','; 43 } 44 row = row.slice(0, -1); 45 CSV += row + '\r\n'; 46 } 47 // 具体的数据处理 48 data.map(function (n: any) { 49 row = ''; 50 // 如果存在自定义key值 51 if (columns.key.length) { 52 columns.key.map(function (m: any, idx: number) { 53 let strItem = n[m]; 54 if (typeof n[m] == 'undefined') { 55 strItem = ''; 56 } else if (typeof n[m] == 'object') { 57 strItem = JSON.stringify(n[m]); 58 strItem = strItem.replaceAll('"', ''); 59 } 60 if (idx === 0 && typeof n['depthCSV'] !== 'undefined') { 61 row += 62 '"' + 63 that.treeDepth(n['depthCSV']) + 64 (typeof columns.formatter === 'function' ? columns.formatter(m, n[m]) || n[m] : strItem) + 65 '",'; 66 } else { 67 row += 68 '"' + (typeof columns.formatter === 'function' ? columns.formatter(m, n[m]) || n[m] : strItem) + '",'; 69 } 70 }); 71 } else { 72 for (key in n) { 73 row += 74 '"' + (typeof columns.formatter === 'function' ? columns.formatter(key, n[key]) || n[key] : n[key]) + '",'; 75 } 76 } 77 row.slice(0, row.length - 1); // 删除最后一个, 78 CSV += row + '\r\n'; // 添加换行符号 79 }); 80 if (!CSV) return; 81 this.SaveAs(fileName, CSV); 82 } 83 84 static SaveAs(fileName: any, csvData: any) { 85 let bw: any = this.browser(); 86 if (!bw['edge'] || !bw['ie']) { 87 let alink: any = document.createElement('a'); 88 alink.id = 'linkDwnldLink'; 89 alink.href = this.getDownloadUrl(csvData); 90 document.body.appendChild(alink); 91 let linkDom: any = document.getElementById('linkDwnldLink'); 92 linkDom.setAttribute('download', fileName); 93 linkDom.click(); 94 document.body.removeChild(linkDom); 95 } else if (bw['ie'] >= 10 || bw['edge'] == 'edge') { 96 let _utf = '\uFEFF'; 97 let _csvData = new Blob([_utf + csvData], { 98 type: 'text/csv', 99 }); 100 (navigator as any).msSaveBlob(_csvData, fileName); 101 } else { 102 let oWin: any = window.top?.open('about:blank', '_blank'); 103 oWin.document.write('sep=,\r\n' + csvData); 104 oWin.document.close(); 105 oWin.document.execCommand('SaveAs', true, fileName); 106 oWin.close(); 107 } 108 } 109 110 static getDownloadUrl(csvData: any) { 111 let _utf = '\uFEFF'; 112 if (window.Blob && window.URL && (window.URL as any).createObjectURL) { 113 var csvData: any = new Blob([_utf + csvData], { 114 type: 'text/csv', 115 }); 116 return URL.createObjectURL(csvData); 117 } 118 } 119 120 static browser() { 121 let Sys: any = {}; 122 let ua = navigator.userAgent.toLowerCase(); 123 let s; 124 (s = ua.indexOf('edge') !== -1 ? (Sys.edge = 'edge') : ua.match(/rv:([\d.]+)\) like gecko/)) 125 ? (Sys.ie = s[1]) 126 : (s = ua.match(/msie ([\d.]+)/)) 127 ? (Sys.ie = s[1]) 128 : (s = ua.match(/firefox\/([\d.]+)/)) 129 ? (Sys.firefox = s[1]) 130 : (s = ua.match(/chrome\/([\d.]+)/)) 131 ? (Sys.chrome = s[1]) 132 : (s = ua.match(/opera.([\d.]+)/)) 133 ? (Sys.opera = s[1]) 134 : (s = ua.match(/version\/([\d.]+).*safari/)) 135 ? (Sys.safari = s[1]) 136 : 0; 137 return Sys; 138 } 139 140 static treeDepth(depth: number) { 141 let str = ''; 142 for (let i = 0; i < depth; i++) { 143 str += ' '; 144 } 145 return str; 146 } 147 148 static treeToArr(data: any) { 149 const result: Array<any> = []; 150 data.forEach((item: any) => { 151 let depthCSV = 0; 152 const loop = (data: any, depth: any) => { 153 result.push({ depthCSV: depth, ...data }); 154 let child = data.children; 155 if (child) { 156 for (let i = 0; i < child.length; i++) { 157 loop(child[i], depth + 1); 158 } 159 } 160 }; 161 loop(item, depthCSV); 162 }); 163 return result; 164 } 165 166 static columnDatas(columns: Array<any>) { 167 let titleList: Array<any> = []; 168 let ketList: Array<any> = []; 169 columns.forEach((column) => { 170 let dataIndex = column.getAttribute('data-index'); 171 let columnName = column.getAttribute('title'); 172 if (columnName == '') { 173 columnName = dataIndex; 174 } 175 if (columnName !== ' ') { 176 titleList.push(columnName); 177 ketList.push(dataIndex); 178 } 179 }); 180 return { 181 titleList: titleList, 182 ketList: ketList, 183 }; 184 } 185 186 static async csvExport(dataSource: { columns: any[]; tables: any[]; fileName: string }): Promise<string> { 187 return new Promise((resolve) => { 188 let data: any = this.columnDatas(dataSource.columns); 189 let resultArr = JSonToCSV.treeToArr(dataSource.tables); 190 JSonToCSV.setDataConver({ 191 data: resultArr, 192 fileName: dataSource.fileName, 193 columns: { 194 title: data.titleList, 195 key: data.ketList, 196 }, 197 }); 198 resolve('ok'); 199 }); 200 } 201} 202