export.js
2.74 KB
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { Router } from 'express'
import xlsx from 'xlsx'
import { getCache, searchInCache } from '../cache.js'
const router = Router()
/**
* 导出Excel
* GET /api/export/excel/:queryId?keyword=xxx
*/
router.get('/excel/:queryId', (req, res) => {
try {
const { queryId } = req.params
const keyword = req.query.keyword || ''
const fileName = req.query.fileName || `query_result_${Date.now()}`
const entry = keyword ? searchInCache(queryId, keyword) : getCache(queryId)
if (!entry) {
return res.json({ success: false, message: '查询结果已过期,请重新执行' })
}
// 构建Excel
const wb = xlsx.utils.book_new()
const wsData = [entry.columns]
for (const row of entry.data) {
const rowData = entry.columns.map(col => {
const val = row[col]
// 处理Buffer类型(如BLOB字段)
if (Buffer.isBuffer(val)) return val.toString('hex')
// 处理Date类型
if (val instanceof Date) return val.toISOString().replace('T', ' ').replace(/\.\d+Z$/, '')
return val
})
wsData.push(rowData)
}
const ws = xlsx.utils.aoa_to_sheet(wsData)
// 设置列宽
ws['!cols'] = entry.columns.map(col => ({
wch: Math.max(col.length * 2, 12),
}))
xlsx.utils.book_append_sheet(wb, ws, '查询结果')
// 生成Buffer
const buf = xlsx.write(wb, { type: 'buffer', bookType: 'xlsx' })
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
res.setHeader('Content-Disposition', `attachment; filename=${encodeURIComponent(fileName)}.xlsx`)
res.send(buf)
} catch (e) {
res.json({ success: false, message: e.message })
}
})
/**
* 导入Excel,返回第一列数据(用于IN条件)
* POST /api/export/import
* multipart/form-data,字段名:file
*/
router.post('/import', (req, res) => {
try {
// 这里使用简单的base64方式上传,避免引入multer
const { fileData, fileName } = req.body
if (!fileData) {
return res.json({ success: false, message: '未接收到文件数据' })
}
// base64转Buffer
const buf = Buffer.from(fileData, 'base64')
const wb = xlsx.read(buf, { type: 'buffer' })
const ws = wb.Sheets[wb.SheetNames[0]]
const data = xlsx.utils.sheet_to_json(ws, { header: 1 })
// 取第一列(跳过表头)
const values = []
for (let i = 1; i < data.length; i++) {
const val = data[i] && data[i][0]
if (val !== undefined && val !== null && String(val).trim() !== '') {
values.push(String(val).trim())
}
}
res.json({ success: true, data: { values, count: values.length } })
} catch (e) {
res.json({ success: false, message: e.message })
}
})
export default router