UNPKG

ng-cw-v12

Version:

Angular UI component library

323 lines (314 loc) 16 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('xlsx-js-style')) : typeof define === 'function' && define.amd ? define('ng-cw-v12/excel-service', ['exports', '@angular/core', 'xlsx-js-style'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global["ng-cw-v12"] = global["ng-cw-v12"] || {}, global["ng-cw-v12"]["excel-service"] = {}), global.ng.core, global.XLSX)); })(this, (function (exports, i0, XLSX) { 'use strict'; function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var i0__namespace = /*#__PURE__*/_interopNamespace(i0); var XLSX__namespace = /*#__PURE__*/_interopNamespace(XLSX); var NcExcelService = /** @class */ (function () { function NcExcelService() { } /** * 导出Excel,表头支持多级和合并 * @param headers 表头配置数组,支持多级和合并单元格 * @param data 要导出的数据数组,每个元素为一个对象,对象的属性需要与表头的key对应 * @param filename 导出的文件名(不需要包含.xlsx后缀) * @param maxWordCount 单元格最大字数,超过此数量将自动换行显示,默认值:10 * @returns 直接触发文件下载,不返回值 */ NcExcelService.prototype.exportExcel = function (headers, data, filename, maxWordCount) { var _this = this; if (maxWordCount === void 0) { maxWordCount = 10; } // 创建工作簿和工作表 var wb = XLSX__namespace.utils.book_new(); var ws = XLSX__namespace.utils.json_to_sheet([]); // 处理表头 var headerRows = this.processHeaders(headers); XLSX__namespace.utils.sheet_add_aoa(ws, headerRows, { origin: 'A1' }); // 获取所有有效的键 var validKeys = this.getValidKeys(headers); // 过滤并转换数据 var filteredData = data.map(function (item) { return _this.filterData(item, validKeys); }); // 添加过滤后的数据 XLSX__namespace.utils.sheet_add_json(ws, filteredData, { origin: { r: headerRows.length, c: 0 }, skipHeader: true }); // 设置合并单元格 ws['!merges'] = this.getMerges(headers); // 设置单元格样式(居中对齐) this.setCellStyles(ws, headerRows.length, maxWordCount); // 将工作表添加到工作簿 XLSX__namespace.utils.book_append_sheet(wb, ws, 'Sheet1'); // 导出Excel文件 XLSX__namespace.writeFile(wb, filename + ".xlsx"); }; NcExcelService.prototype.processHeaders = function (headers) { var result = []; var maxDepth = this.getMaxDepth(headers); for (var i = 0; i < maxDepth; i++) { result.push([]); } var fillHeaders = function (headers, depth, colIndex) { if (depth === void 0) { depth = 0; } if (colIndex === void 0) { colIndex = 0; } headers.forEach(function (header) { var colspan = header.colspan || 1; var rowspan = header.rowspan || 1; // 填充当前单元格 result[depth][colIndex] = header.label; // 如果有子项,递归处理 if (header.children) { fillHeaders(header.children, depth + 1, colIndex); } else { // 如果没有子项,填充空白单元格 for (var i = depth + 1; i < maxDepth; i++) { result[i][colIndex] = ''; } } // 处理跨列 for (var i = 1; i < colspan; i++) { result[depth][colIndex + i] = ''; } // 处理跨行 for (var i = 1; i < rowspan; i++) { if (!result[depth + i]) { result[depth + i] = []; } result[depth + i][colIndex] = ''; } colIndex += colspan; }); }; fillHeaders(headers); return result; }; NcExcelService.prototype.getMaxDepth = function (headers, depth) { var _this = this; if (depth === void 0) { depth = 1; } var maxDepth = depth; headers.forEach(function (header) { if (header.children) { var childDepth = _this.getMaxDepth(header.children, depth + 1); maxDepth = Math.max(maxDepth, childDepth); } }); return maxDepth; }; NcExcelService.prototype.getValidKeys = function (headers) { var keys = []; var extractKeys = function (headers) { headers.forEach(function (header) { if (header.children) { extractKeys(header.children); } else { if (header.key) { keys.push(header.key); } } }); }; extractKeys(headers); return keys; }; NcExcelService.prototype.filterData = function (item, validKeys) { var filteredItem = {}; validKeys.forEach(function (key) { var _a; filteredItem[key] = (_a = item[key]) !== null && _a !== void 0 ? _a : ''; }); return filteredItem; }; NcExcelService.prototype.getMerges = function (headers) { var merges = []; var colIndex = 0; var processMerges = function (headers, rowIndex) { if (rowIndex === void 0) { rowIndex = 0; } headers.forEach(function (header) { var colspan = header.colspan || 1; var rowspan = header.rowspan || 1; if (colspan > 1 || rowspan > 1) { merges.push({ s: { r: rowIndex, c: colIndex }, e: { r: rowIndex + rowspan - 1, c: colIndex + colspan - 1 } }); } if (header.children) { processMerges(header.children, rowIndex + 1); } else { colIndex += colspan; } }); }; processMerges(headers); return merges; }; NcExcelService.prototype.setCellStyles = function (ws, headerRows, maxWordCount) { if (!ws['!cols']) ws['!cols'] = []; if (!ws['!rows']) ws['!rows'] = []; var range = XLSX__namespace.utils.decode_range(ws['!ref'] || 'A1:Z1000'); // 列宽 var maxLengths = this.getMaxLengths(ws, range); //每列的最大字数,例:[10,3,4,5,6,15] for (var i = 0; i <= range.e.c; i++) { ws['!cols'][i] = { wch: Math.max(8, Math.min(this.mathMultiply(maxWordCount, 2.829), this.mathMultiply(maxLengths[i], 2.829))) }; //字体大小为13px时,字数为11,会在28.43宽度时换行,测试时excel会在设置的宽度上加0.14,所以设置单个字宽度为2.829 } //单元格样式和行高 for (var R = range.s.r; R <= range.e.r; R++) { var maxLines = 1; //当前行内单元格最大文字行数 var isHeader = R < headerRows; var isEvenRow = R % 2 === 0; for (var C = range.s.c; C <= range.e.c; C++) { var cellAddress = XLSX__namespace.utils.encode_cell({ r: R, c: C }); if (!ws[cellAddress]) continue; if (!ws[cellAddress].s) ws[cellAddress].s = {}; // 计算单元格内容的行数 var cellValue = String(ws[cellAddress].v || ''); var cellWidth = ws['!cols'][C].wch || 8; var totalWidth = this.mathMultiply(this.getAdjustedLength(cellValue), 2.829); var lines = Math.ceil(this.mathDivide(totalWidth, cellWidth)); maxLines = Math.max(maxLines, lines); ws[cellAddress].s = { alignment: { vertical: 'center', horizontal: 'center', wrapText: true }, font: { name: '仿宋', sz: 13, bold: isHeader, color: { rgb: isHeader ? 'FFFFFF' : '000000' } }, fill: { fgColor: { rgb: isHeader ? "538dd5" : (isEvenRow ? "F2F2F2" : "FFFFFF") } }, border: { top: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } }, bottom: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } }, left: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } }, right: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } } } }; } // 设置行高 var baseHeight = isHeader ? 30 : 25; var lineHeight = isHeader ? 20 : 18; ws['!rows'][R] = { hpt: Math.max(baseHeight, lineHeight * maxLines) }; } }; NcExcelService.prototype.getMaxLengths = function (ws, range) { var maxLengths = []; for (var C = range.s.c; C <= range.e.c; C++) { var maxLength = 0; for (var R = range.s.r; R <= range.e.r; R++) { var cellAddress = XLSX__namespace.utils.encode_cell({ r: R, c: C }); if (ws[cellAddress] && ws[cellAddress].v) { var cellValue = String(ws[cellAddress].v); var adjustedLength = this.getAdjustedLength(cellValue); maxLength = Math.max(maxLength, adjustedLength); } } maxLengths[C] = maxLength; } return maxLengths; }; NcExcelService.prototype.getAdjustedLength = function (value) { var length = 0; for (var i = 0; i < value.length; i++) { if (/[\u4e00-\u9fa5]/.test(value[i])) { length += 1; // 中文字符 } else if (/[a-zA-Z0-9]/.test(value[i])) { length += 0.5; // 英文字母和数字 } else { length += 1; // 其他字符 } } return length; }; NcExcelService.prototype.mathMultiply = function (value1, value2) { // 将浮点数转换为字符串 var aStr = value1.toString(); var bStr = value2.toString(); // 找到小数点后的位置 var aDecimals = (aStr.split('.')[1] || '').length; var bDecimals = (bStr.split('.')[1] || '').length; // 将浮点数转换为整数 var aInt = parseInt(aStr.replace('.', '')); var bInt = parseInt(bStr.replace('.', '')); // 进行整数乘法 var resultInt = aInt * bInt; // 计算最终的小数位数 var totalDecimals = aDecimals + bDecimals; // 将结果转换回浮点数 return resultInt / Math.pow(10, totalDecimals); }; NcExcelService.prototype.mathDivide = function (value1, value2) { // 将浮点数转换为字符串 var aStr = value1.toString(); var bStr = value2.toString(); // 找到小数点后的位置 var aDecimals = (aStr.split('.')[1] || '').length; var bDecimals = (bStr.split('.')[1] || '').length; // 找到最大的小数位数 var maxDecimals = Math.max(aDecimals, bDecimals); // 将浮点数转换为整数 var aInt = Math.round(value1 * Math.pow(10, maxDecimals)); var bInt = Math.round(value2 * Math.pow(10, maxDecimals)); // 进行整数除法并直接返回结果 return aInt / bInt; }; return NcExcelService; }()); NcExcelService.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0__namespace, type: NcExcelService, deps: [], target: i0__namespace.ɵɵFactoryTarget.Injectable }); NcExcelService.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0__namespace, type: NcExcelService }); i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0__namespace, type: NcExcelService, decorators: [{ type: i0.Injectable }] }); var NcExcelServiceModule = /** @class */ (function () { function NcExcelServiceModule() { } return NcExcelServiceModule; }()); NcExcelServiceModule.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0__namespace, type: NcExcelServiceModule, deps: [], target: i0__namespace.ɵɵFactoryTarget.NgModule }); NcExcelServiceModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0__namespace, type: NcExcelServiceModule }); NcExcelServiceModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0__namespace, type: NcExcelServiceModule, providers: [NcExcelService] }); i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0__namespace, type: NcExcelServiceModule, decorators: [{ type: i0.NgModule, args: [{ providers: [NcExcelService] }] }] }); /** * Generated bundle index. Do not edit. */ exports.NcExcelService = NcExcelService; exports.NcExcelServiceModule = NcExcelServiceModule; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=ng-cw-v12-excel-service.umd.js.map