@templmf/temp-solf-lmf 0.0.2 → 0.0.3
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 +1 -1
- package/vue2toxlsx.txt +43 -395
package/package.json
CHANGED
package/vue2toxlsx.txt
CHANGED
|
@@ -1,399 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
h1 {
|
|
33
|
-
text-align: center;
|
|
34
|
-
color: #333;
|
|
35
|
-
margin-bottom: 30px;
|
|
36
|
-
font-size: 2rem;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.data-section {
|
|
40
|
-
margin-bottom: 30px;
|
|
41
|
-
padding: 20px;
|
|
42
|
-
background: #f8f9fa;
|
|
43
|
-
border-radius: 10px;
|
|
44
|
-
border: 1px solid #e9ecef;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.data-section h3 {
|
|
48
|
-
color: #495057;
|
|
49
|
-
margin-bottom: 15px;
|
|
50
|
-
font-size: 1.2rem;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.data-preview {
|
|
54
|
-
background: white;
|
|
55
|
-
border-radius: 8px;
|
|
56
|
-
padding: 15px;
|
|
57
|
-
max-height: 300px;
|
|
58
|
-
overflow-y: auto;
|
|
59
|
-
border: 1px solid #dee2e6;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.data-table {
|
|
63
|
-
width: 100%;
|
|
64
|
-
border-collapse: collapse;
|
|
65
|
-
font-size: 14px;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.data-table th,
|
|
69
|
-
.data-table td {
|
|
70
|
-
padding: 8px 12px;
|
|
71
|
-
text-align: left;
|
|
72
|
-
border-bottom: 1px solid #dee2e6;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.data-table th {
|
|
76
|
-
background: #f8f9fa;
|
|
77
|
-
font-weight: 600;
|
|
78
|
-
color: #495057;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.data-table tbody tr:hover {
|
|
82
|
-
background: #f8f9fa;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.export-btn {
|
|
86
|
-
display: block;
|
|
87
|
-
width: 200px;
|
|
88
|
-
margin: 30px auto;
|
|
89
|
-
padding: 15px 30px;
|
|
90
|
-
background: linear-gradient(135deg, #28a745, #20c997);
|
|
91
|
-
color: white;
|
|
92
|
-
border: none;
|
|
93
|
-
border-radius: 50px;
|
|
94
|
-
font-size: 16px;
|
|
95
|
-
font-weight: 600;
|
|
96
|
-
cursor: pointer;
|
|
97
|
-
transition: all 0.3s ease;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.export-btn:hover {
|
|
101
|
-
transform: translateY(-2px);
|
|
102
|
-
box-shadow: 0 8px 20px rgba(40, 167, 69, 0.3);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.export-btn:disabled {
|
|
106
|
-
background: #6c757d;
|
|
107
|
-
cursor: not-allowed;
|
|
108
|
-
transform: none;
|
|
109
|
-
box-shadow: none;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.stats {
|
|
113
|
-
display: flex;
|
|
114
|
-
justify-content: space-around;
|
|
115
|
-
background: #495057;
|
|
116
|
-
color: white;
|
|
117
|
-
padding: 15px;
|
|
118
|
-
border-radius: 10px;
|
|
119
|
-
margin-bottom: 20px;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.stat-item {
|
|
123
|
-
text-align: center;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.stat-number {
|
|
127
|
-
font-size: 1.5rem;
|
|
128
|
-
font-weight: bold;
|
|
129
|
-
display: block;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.stat-label {
|
|
133
|
-
font-size: 0.9rem;
|
|
134
|
-
opacity: 0.8;
|
|
135
|
-
}
|
|
136
|
-
</style>
|
|
137
|
-
</head>
|
|
138
|
-
<body>
|
|
139
|
-
<div id="app">
|
|
140
|
-
<div class="container">
|
|
141
|
-
<h1>📊 Vue2 JSON导出Excel</h1>
|
|
142
|
-
|
|
143
|
-
<div class="stats">
|
|
144
|
-
<div class="stat-item">
|
|
145
|
-
<span class="stat-number">{{ jsonData1.length }}</span>
|
|
146
|
-
<span class="stat-label">员工数据</span>
|
|
147
|
-
</div>
|
|
148
|
-
<div class="stat-item">
|
|
149
|
-
<span class="stat-number">{{ jsonData2.length }}</span>
|
|
150
|
-
<span class="stat-label">产品数据</span>
|
|
151
|
-
</div>
|
|
152
|
-
<div class="stat-item">
|
|
153
|
-
<span class="stat-number">{{ jsonData3.length }}</span>
|
|
154
|
-
<span class="stat-label">订单数据</span>
|
|
155
|
-
</div>
|
|
156
|
-
<div class="stat-item">
|
|
157
|
-
<span class="stat-number">{{ totalCount }}</span>
|
|
158
|
-
<span class="stat-label">总计</span>
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
|
|
162
|
-
<div class="data-section">
|
|
163
|
-
<h3>👥 员工数据 ({{ jsonData1.length }} 条)</h3>
|
|
164
|
-
<div class="data-preview">
|
|
165
|
-
<table class="data-table" v-if="jsonData1.length > 0">
|
|
166
|
-
<thead>
|
|
167
|
-
<tr>
|
|
168
|
-
<th v-for="key in getKeys(jsonData1)" :key="key">{{ key }}</th>
|
|
169
|
-
</tr>
|
|
170
|
-
</thead>
|
|
171
|
-
<tbody>
|
|
172
|
-
<tr v-for="(item, index) in jsonData1" :key="index">
|
|
173
|
-
<td v-for="key in getKeys(jsonData1)" :key="key">{{ item[key] || '-' }}</td>
|
|
174
|
-
</tr>
|
|
175
|
-
</tbody>
|
|
176
|
-
</table>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
|
|
180
|
-
<div class="data-section">
|
|
181
|
-
<h3>📦 产品数据 ({{ jsonData2.length }} 条)</h3>
|
|
182
|
-
<div class="data-preview">
|
|
183
|
-
<table class="data-table" v-if="jsonData2.length > 0">
|
|
184
|
-
<thead>
|
|
185
|
-
<tr>
|
|
186
|
-
<th v-for="key in getKeys(jsonData2)" :key="key">{{ key }}</th>
|
|
187
|
-
</tr>
|
|
188
|
-
</thead>
|
|
189
|
-
<tbody>
|
|
190
|
-
<tr v-for="(item, index) in jsonData2" :key="index">
|
|
191
|
-
<td v-for="key in getKeys(jsonData2)" :key="key">{{ item[key] || '-' }}</td>
|
|
192
|
-
</tr>
|
|
193
|
-
</tbody>
|
|
194
|
-
</table>
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
|
|
198
|
-
<div class="data-section">
|
|
199
|
-
<h3>📋 订单数据 ({{ jsonData3.length }} 条)</h3>
|
|
200
|
-
<div class="data-preview">
|
|
201
|
-
<table class="data-table" v-if="jsonData3.length > 0">
|
|
202
|
-
<thead>
|
|
203
|
-
<tr>
|
|
204
|
-
<th v-for="key in getKeys(jsonData3)" :key="key">{{ key }}</th>
|
|
205
|
-
</tr>
|
|
206
|
-
</thead>
|
|
207
|
-
<tbody>
|
|
208
|
-
<tr v-for="(item, index) in jsonData3" :key="index">
|
|
209
|
-
<td v-for="key in getKeys(jsonData3)" :key="key">{{ item[key] || '-' }}</td>
|
|
210
|
-
</tr>
|
|
211
|
-
</tbody>
|
|
212
|
-
</table>
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
215
|
-
|
|
216
|
-
<button class="export-btn" @click="exportToExcel" :disabled="totalCount === 0">
|
|
217
|
-
🚀 导出Excel ({{ totalCount }} 条数据)
|
|
218
|
-
</button>
|
|
219
|
-
</div>
|
|
220
|
-
</div>
|
|
221
|
-
|
|
222
|
-
<script>
|
|
223
|
-
new Vue({
|
|
224
|
-
el: '#app',
|
|
225
|
-
data: {
|
|
226
|
-
// 员工数据
|
|
227
|
-
jsonData1: [
|
|
228
|
-
{
|
|
229
|
-
"姓名": "张三",
|
|
230
|
-
"年龄": 25,
|
|
231
|
-
"部门": "技术部",
|
|
232
|
-
"薪资": 8000,
|
|
233
|
-
"入职日期": "2023-01-15"
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
"姓名": "李四",
|
|
237
|
-
"年龄": 28,
|
|
238
|
-
"部门": "销售部",
|
|
239
|
-
"薪资": 7500,
|
|
240
|
-
"入职日期": "2022-08-20"
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
"姓名": "王五",
|
|
244
|
-
"年龄": 32,
|
|
245
|
-
"部门": "市场部",
|
|
246
|
-
"薪资": 9000,
|
|
247
|
-
"入职日期": "2021-03-10"
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
"姓名": "赵六",
|
|
251
|
-
"年龄": 26,
|
|
252
|
-
"部门": "技术部",
|
|
253
|
-
"薪资": 8500,
|
|
254
|
-
"入职日期": "2023-05-20"
|
|
255
|
-
}
|
|
256
|
-
],
|
|
257
|
-
|
|
258
|
-
// 产品数据
|
|
259
|
-
jsonData2: [
|
|
260
|
-
{
|
|
261
|
-
"产品ID": "P001",
|
|
262
|
-
"产品名称": "iPhone 15",
|
|
263
|
-
"价格": 5999,
|
|
264
|
-
"库存": 100,
|
|
265
|
-
"分类": "手机"
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"产品ID": "P002",
|
|
269
|
-
"产品名称": "MacBook Pro",
|
|
270
|
-
"价格": 12999,
|
|
271
|
-
"库存": 50,
|
|
272
|
-
"分类": "电脑"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
"产品ID": "P003",
|
|
276
|
-
"产品名称": "iPad Air",
|
|
277
|
-
"价格": 4399,
|
|
278
|
-
"库存": 75,
|
|
279
|
-
"分类": "平板"
|
|
280
|
-
}
|
|
281
|
-
],
|
|
282
|
-
|
|
283
|
-
// 订单数据
|
|
284
|
-
jsonData3: [
|
|
285
|
-
{
|
|
286
|
-
"订单号": "ORD001",
|
|
287
|
-
"客户名称": "王先生",
|
|
288
|
-
"产品": "iPhone 15",
|
|
289
|
-
"数量": 2,
|
|
290
|
-
"金额": 11998,
|
|
291
|
-
"销售日期": "2023-11-01"
|
|
292
|
-
},
|
|
293
|
-
{
|
|
294
|
-
"订单号": "ORD002",
|
|
295
|
-
"客户名称": "李女士",
|
|
296
|
-
"产品": "MacBook Pro",
|
|
297
|
-
"数量": 1,
|
|
298
|
-
"金额": 12999,
|
|
299
|
-
"销售日期": "2023-11-02"
|
|
300
|
-
},
|
|
301
|
-
{
|
|
302
|
-
"订单号": "ORD003",
|
|
303
|
-
"客户名称": "张总",
|
|
304
|
-
"产品": "iPad Air",
|
|
305
|
-
"数量": 3,
|
|
306
|
-
"金额": 13197,
|
|
307
|
-
"销售日期": "2023-11-03"
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
"订单号": "ORD004",
|
|
311
|
-
"客户名称": "陈经理",
|
|
312
|
-
"产品": "iPhone 15",
|
|
313
|
-
"数量": 1,
|
|
314
|
-
"金额": 5999,
|
|
315
|
-
"销售日期": "2023-11-04"
|
|
316
|
-
},
|
|
317
|
-
{
|
|
318
|
-
"订单号": "ORD005",
|
|
319
|
-
"客户名称": "刘老师",
|
|
320
|
-
"产品": "MacBook Pro",
|
|
321
|
-
"数量": 2,
|
|
322
|
-
"金额": 25998,
|
|
323
|
-
"销售日期": "2023-11-05"
|
|
1
|
+
// 设置工作表样式
|
|
2
|
+
setWorksheetStyle(worksheet) {
|
|
3
|
+
if (!worksheet['!ref']) return;
|
|
4
|
+
|
|
5
|
+
const range = XLSX.utils.decode_range(worksheet['!ref']);
|
|
6
|
+
|
|
7
|
+
// 设置列宽
|
|
8
|
+
const cols = [];
|
|
9
|
+
for (let c = range.s.c; c <= range.e.c; c++) {
|
|
10
|
+
cols.push({ wch: 15 });
|
|
11
|
+
}
|
|
12
|
+
worksheet['!cols'] = cols;
|
|
13
|
+
|
|
14
|
+
// 设置字体和样式
|
|
15
|
+
for (let r = range.s.r; r <= range.e.r; r++) {
|
|
16
|
+
for (let c = range.s.c; c <= range.e.c; c++) {
|
|
17
|
+
const cellAddress = XLSX.utils.encode_cell({ r: r, c: c });
|
|
18
|
+
if (worksheet[cellAddress]) {
|
|
19
|
+
// 所有单元格设置微软雅黑字体
|
|
20
|
+
worksheet[cellAddress].s = {
|
|
21
|
+
font: {
|
|
22
|
+
name: "微软雅黑",
|
|
23
|
+
sz: 11,
|
|
24
|
+
bold: r === 0 // 第一行(表头)加粗
|
|
25
|
+
},
|
|
26
|
+
alignment: {
|
|
27
|
+
vertical: "center",
|
|
28
|
+
horizontal: "left"
|
|
324
29
|
}
|
|
325
|
-
|
|
326
|
-
},
|
|
327
|
-
|
|
328
|
-
computed: {
|
|
329
|
-
totalCount() {
|
|
330
|
-
return this.jsonData1.length + this.jsonData2.length + this.jsonData3.length;
|
|
331
|
-
}
|
|
332
|
-
},
|
|
333
|
-
|
|
334
|
-
methods: {
|
|
335
|
-
// 获取对象数组的所有键名
|
|
336
|
-
getKeys(dataArray) {
|
|
337
|
-
if (!dataArray || dataArray.length === 0) return [];
|
|
338
|
-
return Object.keys(dataArray[0]);
|
|
339
|
-
},
|
|
30
|
+
};
|
|
340
31
|
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// 添加产品数据工作表
|
|
355
|
-
if (this.jsonData2.length > 0) {
|
|
356
|
-
const ws2 = XLSX.utils.json_to_sheet(this.jsonData2);
|
|
357
|
-
this.setColumnWidth(ws2);
|
|
358
|
-
XLSX.utils.book_append_sheet(wb, ws2, '产品信息');
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// 添加订单数据工作表
|
|
362
|
-
if (this.jsonData3.length > 0) {
|
|
363
|
-
const ws3 = XLSX.utils.json_to_sheet(this.jsonData3);
|
|
364
|
-
this.setColumnWidth(ws3);
|
|
365
|
-
XLSX.utils.book_append_sheet(wb, ws3, '订单信息');
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// 生成文件名
|
|
369
|
-
const now = new Date();
|
|
370
|
-
const fileName = `数据导出_${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}_${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}.xlsx`;
|
|
371
|
-
|
|
372
|
-
// 导出文件
|
|
373
|
-
XLSX.writeFile(wb, fileName);
|
|
374
|
-
|
|
375
|
-
alert(`Excel文件导出成功!\n文件名:${fileName}\n包含 ${Object.keys(wb.Sheets).length} 个工作表,共 ${this.totalCount} 条数据`);
|
|
376
|
-
} catch (error) {
|
|
377
|
-
alert(`导出失败:${error.message}`);
|
|
378
|
-
console.error('导出错误:', error);
|
|
379
|
-
}
|
|
380
|
-
},
|
|
381
|
-
|
|
382
|
-
// 设置列宽
|
|
383
|
-
setColumnWidth(worksheet) {
|
|
384
|
-
if (!worksheet['!ref']) return;
|
|
385
|
-
|
|
386
|
-
const range = XLSX.utils.decode_range(worksheet['!ref']);
|
|
387
|
-
const cols = [];
|
|
388
|
-
|
|
389
|
-
for (let c = range.s.c; c <= range.e.c; c++) {
|
|
390
|
-
cols.push({ wch: 15 });
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
worksheet['!cols'] = cols;
|
|
32
|
+
// 表头额外样式
|
|
33
|
+
if (r === 0) {
|
|
34
|
+
worksheet[cellAddress].s.fill = {
|
|
35
|
+
fgColor: { rgb: "F2F2F2" }
|
|
36
|
+
};
|
|
37
|
+
worksheet[cellAddress].s.border = {
|
|
38
|
+
top: { style: "thin", color: { rgb: "D0D0D0" } },
|
|
39
|
+
bottom: { style: "thin", color: { rgb: "D0D0D0" } },
|
|
40
|
+
left: { style: "thin", color: { rgb: "D0D0D0" } },
|
|
41
|
+
right: { style: "thin", color: { rgb: "D0D0D0" } }
|
|
42
|
+
};
|
|
394
43
|
}
|
|
395
44
|
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
</html>
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|