bl-common-vue3 3.8.109 → 3.8.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bl-common-vue3",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.110",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"module": "index.js",
|
|
6
6
|
"description": "bailing vue3 common components lib",
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
"file-saver": "^2.0.5",
|
|
42
42
|
"style-resources-loader": "^1.5.0"
|
|
43
43
|
},
|
|
44
|
-
"dependencies": {
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"xlsx-js-style": "^1.2.0"
|
|
46
|
+
},
|
|
45
47
|
"devDependencies": {
|
|
46
48
|
"@vue/cli-plugin-babel": "~4.5.13",
|
|
47
49
|
"@vue/cli-plugin-eslint": "~4.5.13",
|
package/src/common/utils/xlsx.js
CHANGED
|
@@ -1,7 +1,40 @@
|
|
|
1
|
-
import fs from "file-saver";
|
|
2
|
-
import * as
|
|
1
|
+
import fs from "file-saver";
|
|
2
|
+
import * as LegacyXLSX from "kj-xlsx";
|
|
3
|
+
|
|
4
|
+
const DEFAULT_COLUMN_WIDTH = 16;
|
|
5
|
+
const MAX_COLUMN_WIDTH = 36;
|
|
6
|
+
const HEADER_ROW_HEIGHT = 30;
|
|
7
|
+
const DATA_ROW_HEIGHT = 24;
|
|
8
|
+
|
|
9
|
+
const createBorder = (color) => ({
|
|
10
|
+
top: { style: "thin", color: { rgb: color } },
|
|
11
|
+
bottom: { style: "thin", color: { rgb: color } },
|
|
12
|
+
left: { style: "thin", color: { rgb: color } },
|
|
13
|
+
right: { style: "thin", color: { rgb: color } },
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const getStyledExportOptions = (options = {}) => {
|
|
17
|
+
// 公共导出默认使用统一基础样式,特殊旧模板仍可通过 enabled: false 关闭。
|
|
18
|
+
const {
|
|
19
|
+
enabled = true,
|
|
20
|
+
detailFields = [],
|
|
21
|
+
fieldAlignments = {},
|
|
22
|
+
columnWidths = {},
|
|
23
|
+
} = options;
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
enabled,
|
|
27
|
+
detailFields: Array.isArray(detailFields) ? detailFields : [],
|
|
28
|
+
fieldAlignments:
|
|
29
|
+
fieldAlignments && typeof fieldAlignments === "object"
|
|
30
|
+
? fieldAlignments
|
|
31
|
+
: {},
|
|
32
|
+
columnWidths:
|
|
33
|
+
columnWidths && typeof columnWidths === "object" ? columnWidths : {},
|
|
34
|
+
};
|
|
35
|
+
};
|
|
3
36
|
|
|
4
|
-
export function getVerticalMergeCells(json, fields, options = {}) {
|
|
37
|
+
export function getVerticalMergeCells(json, fields, options = {}) {
|
|
5
38
|
const { groupField, mergeFields = [] } = options;
|
|
6
39
|
if (!groupField || !Array.isArray(mergeFields) || !mergeFields.length) {
|
|
7
40
|
return [];
|
|
@@ -50,13 +83,111 @@ export function getVerticalMergeCells(json, fields, options = {}) {
|
|
|
50
83
|
groupStartIndex = rowIndex;
|
|
51
84
|
}
|
|
52
85
|
|
|
53
|
-
return merges;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
86
|
+
return merges;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const getAutoColumnWidths = (json, fields, columnWidths = {}) => {
|
|
90
|
+
return Object.entries(fields).map(([field, title]) => {
|
|
91
|
+
const configuredWidth = Number(columnWidths[field]);
|
|
92
|
+
if (configuredWidth > 0) {
|
|
93
|
+
return { wch: configuredWidth };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const contentWidth = json.reduce((width, item) => {
|
|
97
|
+
const valueLength = String(item?.[field] ?? "").length;
|
|
98
|
+
return Math.max(width, valueLength);
|
|
99
|
+
}, String(title ?? "").length);
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
wch: Math.min(MAX_COLUMN_WIDTH, Math.max(DEFAULT_COLUMN_WIDTH, contentWidth + 2)),
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const applyStyledExport = (XLSX, ws, json, fields, options) => {
|
|
108
|
+
const fieldKeys = Object.keys(fields);
|
|
109
|
+
const detailFieldSet = new Set(options.detailFields);
|
|
110
|
+
const headerBorder = createBorder("FFB4C7E7");
|
|
111
|
+
const bodyBorder = createBorder("FFD9E2F3");
|
|
112
|
+
|
|
113
|
+
fieldKeys.forEach((field, columnIndex) => {
|
|
114
|
+
const headerCell = ws[XLSX.utils.encode_cell({ r: 0, c: columnIndex })];
|
|
115
|
+
if (headerCell) {
|
|
116
|
+
const isDetailField = detailFieldSet.has(field);
|
|
117
|
+
headerCell.s = {
|
|
118
|
+
font: {
|
|
119
|
+
name: "Microsoft YaHei",
|
|
120
|
+
sz: 11,
|
|
121
|
+
bold: true,
|
|
122
|
+
color: { rgb: isDetailField ? "FF1F4E78" : "FFFFFFFF" },
|
|
123
|
+
},
|
|
124
|
+
fill: {
|
|
125
|
+
patternType: "solid",
|
|
126
|
+
fgColor: { rgb: isDetailField ? "FFDCE6F1" : "FF4472C4" },
|
|
127
|
+
},
|
|
128
|
+
alignment: {
|
|
129
|
+
horizontal: "center",
|
|
130
|
+
vertical: "center",
|
|
131
|
+
wrapText: true,
|
|
132
|
+
},
|
|
133
|
+
border: headerBorder,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
json.forEach((item, dataIndex) => {
|
|
138
|
+
const cell = ws[
|
|
139
|
+
XLSX.utils.encode_cell({ r: dataIndex + 1, c: columnIndex })
|
|
140
|
+
];
|
|
141
|
+
if (!cell) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const isDetailField = detailFieldSet.has(field);
|
|
146
|
+
cell.s = {
|
|
147
|
+
font: {
|
|
148
|
+
name: "Microsoft YaHei",
|
|
149
|
+
sz: 10,
|
|
150
|
+
color: { rgb: "FF333333" },
|
|
151
|
+
},
|
|
152
|
+
fill: {
|
|
153
|
+
patternType: "solid",
|
|
154
|
+
fgColor: { rgb: isDetailField ? "FFF7FAFD" : "FFFFFFFF" },
|
|
155
|
+
},
|
|
156
|
+
alignment: {
|
|
157
|
+
horizontal: options.fieldAlignments[field] || "left",
|
|
158
|
+
vertical: "center",
|
|
159
|
+
wrapText: true,
|
|
160
|
+
},
|
|
161
|
+
border: bodyBorder,
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
ws["!cols"] = getAutoColumnWidths(json, fields, options.columnWidths);
|
|
167
|
+
ws["!rows"] = [
|
|
168
|
+
{ hpt: HEADER_ROW_HEIGHT },
|
|
169
|
+
...json.map(() => ({ hpt: DATA_ROW_HEIGHT })),
|
|
170
|
+
];
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// 暴露工作簿构建方法,便于对合并区域和样式做真实 xlsx 回归检查。
|
|
174
|
+
export async function createWorkbook(
|
|
175
|
+
json,
|
|
176
|
+
fields,
|
|
177
|
+
mergeOptions = {},
|
|
178
|
+
styleOptions = {}
|
|
179
|
+
) {
|
|
180
|
+
const merges = getVerticalMergeCells(json, fields, mergeOptions);
|
|
181
|
+
const styledExportOptions = getStyledExportOptions(styleOptions);
|
|
182
|
+
const styledXLSXModule = styledExportOptions.enabled
|
|
183
|
+
? await import("xlsx-js-style")
|
|
184
|
+
: null;
|
|
185
|
+
const XLSX = styledXLSXModule?.default || styledXLSXModule || LegacyXLSX;
|
|
186
|
+
const sourceJson = styledExportOptions.enabled
|
|
187
|
+
? json.map((item) => ({ ...item }))
|
|
188
|
+
: null;
|
|
189
|
+
//导出xlsx
|
|
190
|
+
json.forEach((item) => {
|
|
60
191
|
for (let i in item) {
|
|
61
192
|
// eslint-disable-next-line no-prototype-builtins
|
|
62
193
|
if (fields.hasOwnProperty(i)) {
|
|
@@ -65,14 +196,33 @@ export function xlsx(json, fields, filename = ".xlsx", mergeOptions = {}) {
|
|
|
65
196
|
delete item[i]; //删除原先的对象属性
|
|
66
197
|
}
|
|
67
198
|
});
|
|
68
|
-
let
|
|
69
|
-
let
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
199
|
+
let wb = XLSX.utils.book_new(); //工作簿对象包含一SheetNames数组,以及一个表对象映射表名称到表对象。XLSX.utils.book_new实用函数创建一个新的工作簿对象。
|
|
200
|
+
let ws = XLSX.utils.json_to_sheet(json, { header: Object.values(fields) }); //将JS对象数组转换为工作表。
|
|
201
|
+
if (merges.length) {
|
|
202
|
+
ws["!merges"] = merges;
|
|
203
|
+
}
|
|
204
|
+
if (styledExportOptions.enabled) {
|
|
205
|
+
applyStyledExport(XLSX, ws, sourceJson, fields, styledExportOptions);
|
|
206
|
+
}
|
|
207
|
+
return { XLSX, wb, ws };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export async function xlsx(
|
|
211
|
+
json,
|
|
212
|
+
fields,
|
|
213
|
+
filename = ".xlsx",
|
|
214
|
+
mergeOptions = {},
|
|
215
|
+
styleOptions = {}
|
|
216
|
+
) {
|
|
217
|
+
const { XLSX, wb, ws } = await createWorkbook(
|
|
218
|
+
json,
|
|
219
|
+
fields,
|
|
220
|
+
mergeOptions,
|
|
221
|
+
styleOptions
|
|
222
|
+
);
|
|
223
|
+
const sheetName = filename.replace(/[\\/?*[\]:]/g, "").slice(0, 31) || "Sheet1"; //excel的文件名称
|
|
224
|
+
wb.SheetNames.push(sheetName);
|
|
225
|
+
wb.Sheets[sheetName] = ws;
|
|
76
226
|
const defaultCellStyle = {
|
|
77
227
|
font: { name: "Verdana", sz: 13, color: "FF00FF88" },
|
|
78
228
|
fill: { fgColor: { rgb: "FFFFAA00" } },
|
|
@@ -67,10 +67,14 @@ export default defineComponent({
|
|
|
67
67
|
type: Object,
|
|
68
68
|
default: () => ({})
|
|
69
69
|
},
|
|
70
|
-
merge_options: { //导出表格纵向合并配置
|
|
71
|
-
type: Object,
|
|
72
|
-
default: () => ({})
|
|
73
|
-
},
|
|
70
|
+
merge_options: { //导出表格纵向合并配置
|
|
71
|
+
type: Object,
|
|
72
|
+
default: () => ({})
|
|
73
|
+
},
|
|
74
|
+
style_options: { //导出表格样式配置
|
|
75
|
+
type: Object,
|
|
76
|
+
default: () => ({})
|
|
77
|
+
},
|
|
74
78
|
custom_result: { //导出表格头部
|
|
75
79
|
type: Object,
|
|
76
80
|
// eslint-disable-next-line vue/require-valid-default-prop
|
|
@@ -125,9 +129,9 @@ export default defineComponent({
|
|
|
125
129
|
context.emit("customDataFunc" , state.ExportList)
|
|
126
130
|
}else {
|
|
127
131
|
console.log('导出文档')
|
|
128
|
-
setTimeout(() => {
|
|
129
|
-
let list = utils.deepClone(state.ExportList);
|
|
130
|
-
xlsx(list, removeUndefined(props.columnstitle), props.title, props.merge_options);
|
|
132
|
+
setTimeout(async () => {
|
|
133
|
+
let list = utils.deepClone(state.ExportList);
|
|
134
|
+
await xlsx(list, removeUndefined(props.columnstitle), props.title, props.merge_options, props.style_options);
|
|
131
135
|
context.emit("success", t('ExportComponents.index.921182-2'));
|
|
132
136
|
closeModal()
|
|
133
137
|
}, 200);
|
|
@@ -142,9 +146,9 @@ export default defineComponent({
|
|
|
142
146
|
context.emit("customDataFunc" , state.ExportList)
|
|
143
147
|
}else {
|
|
144
148
|
console.log('导出文档')
|
|
145
|
-
setTimeout(() => {
|
|
146
|
-
let list = utils.deepClone(state.ExportList);
|
|
147
|
-
xlsx(list, removeUndefined(props.columnstitle), props.title, props.merge_options);
|
|
149
|
+
setTimeout(async () => {
|
|
150
|
+
let list = utils.deepClone(state.ExportList);
|
|
151
|
+
await xlsx(list, removeUndefined(props.columnstitle), props.title, props.merge_options, props.style_options);
|
|
148
152
|
context.emit("success", t('ExportComponents.index.921182-2'));
|
|
149
153
|
closeModal()
|
|
150
154
|
}, 200);
|
|
@@ -162,9 +166,9 @@ export default defineComponent({
|
|
|
162
166
|
watch(
|
|
163
167
|
() => props.custom_result,
|
|
164
168
|
(val) => {
|
|
165
|
-
setTimeout(() => {
|
|
166
|
-
let list = utils.deepClone(val);
|
|
167
|
-
xlsx(list, removeUndefined(props.columnstitle), props.title, props.merge_options);
|
|
169
|
+
setTimeout(async () => {
|
|
170
|
+
let list = utils.deepClone(val);
|
|
171
|
+
await xlsx(list, removeUndefined(props.columnstitle), props.title, props.merge_options, props.style_options);
|
|
168
172
|
context.emit("success", t('ExportComponents.index.921182-2'));
|
|
169
173
|
closeModal()
|
|
170
174
|
}, 200);
|