@sch_cat/export-utils 0.0.2 → 0.0.4
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/README.md +153 -5
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,7 +1,155 @@
|
|
|
1
|
-
|
|
1
|
+
## 📦 @sch_cat/export-utils
|
|
2
|
+
###### 一个轻量级、高性能的 Node.js 数据导出工具,支持 MySQL 和 MongoDB,可将海量数据流式导出为 CSV 文件,并实时跟踪任务进度。
|
|
3
|
+

|
|
4
|
+

|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
##### ✨ 特性
|
|
7
|
+
✅ 流式导出 – 支持百万级数据导出,避免内存溢出(OOM)。
|
|
8
|
+
✅ 双数据库支持 – 原生支持 MySQL 和 MongoDB 表/集合导出。
|
|
9
|
+
✅ 实时进度追踪 – 通过 Redis 存储任务状态(键名:export:taskId)。
|
|
10
|
+
✅ 字段格式化 – 自定义 CSV 中字段的显示格式(如状态转换、日期格式等)。
|
|
11
|
+
✅ Gzip 压缩输出 – 生成 .csv.gz 文件,节省磁盘与带宽。
|
|
12
|
+
✅ TypeScript 友好 – 内置完整类型定义。
|
|
13
|
+
✅ 背压控制 – 自动暂停/恢复数据流,防止内存堆积。
|
|
4
14
|
|
|
5
|
-
|
|
6
|
-
```
|
|
7
|
-
npm install @
|
|
15
|
+
##### 🚀 安装
|
|
16
|
+
```
|
|
17
|
+
npm install @sch_cat/export-utils
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
##### 📖 使用示例
|
|
21
|
+
1. 初始化导出工具
|
|
22
|
+
```
|
|
23
|
+
// export.service.ts
|
|
24
|
+
import { ExportUtils } from '@sch_cat/export-utils';
|
|
25
|
+
|
|
26
|
+
const exportUtils = new ExportUtils({
|
|
27
|
+
redisOptions: {
|
|
28
|
+
host: 'localhost',
|
|
29
|
+
port: 6379,
|
|
30
|
+
},
|
|
31
|
+
mysqlOptions: {
|
|
32
|
+
host: 'localhost',
|
|
33
|
+
user: 'root',
|
|
34
|
+
password: 'password',
|
|
35
|
+
database: 'mydb',
|
|
36
|
+
},
|
|
37
|
+
mongoOptions: {
|
|
38
|
+
url: 'mongodb://localhost:27017',
|
|
39
|
+
options: { useNewUrlParser: true, useUnifiedTopology: true },
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
> 💡 如果只使用一种数据库,可省略另一项配置(如仅用 MySQL,则无需 mongoOptions)。
|
|
44
|
+
2. 从 MySQL 导出数据
|
|
45
|
+
```
|
|
46
|
+
const taskId = await exportUtils.createMysqlExportTask({
|
|
47
|
+
table: 'users', // 表名(自动校验安全性)
|
|
48
|
+
outputPath: 'exports/users.csv', // 相对路径或绝对路径
|
|
49
|
+
columns: [
|
|
50
|
+
{ key: 'id', header: '用户ID' },
|
|
51
|
+
{ key: 'name' }, // header 默认为 key
|
|
52
|
+
{
|
|
53
|
+
key: 'status',
|
|
54
|
+
header: '状态',
|
|
55
|
+
formatter: (val) => (val === 1 ? '启用' : '禁用'), // 自定义格式
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
where: 'created_at > "2024-01-01"', // 可选 SQL WHERE 条件
|
|
59
|
+
batchSize: 2000, // 每批处理行数
|
|
60
|
+
onCompleted: (result) => {
|
|
61
|
+
console.log('✅ 导出完成:', result.outputPath);
|
|
62
|
+
},
|
|
63
|
+
onErr: (err) => {
|
|
64
|
+
console.error('❌ 导出失败:', err.errMsg);
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
console.log('任务ID:', taskId); // 例如:export-mysql-csv-xxxx
|
|
69
|
+
```
|
|
70
|
+
3. 从 MongoDB 导出数据
|
|
71
|
+
```
|
|
72
|
+
const taskId = await exportUtils.createMongoExportTask({
|
|
73
|
+
db: 'myapp',
|
|
74
|
+
collection: 'orders',
|
|
75
|
+
outputPath: 'exports/orders.csv',
|
|
76
|
+
columns: [
|
|
77
|
+
{ key: '_id', header: '订单ID' },
|
|
78
|
+
{ key: 'amount' },
|
|
79
|
+
{ key: 'user.email', header: '邮箱' }, // 支持嵌套字段
|
|
80
|
+
],
|
|
81
|
+
query: { status: 'completed' }, // MongoDB 查询条件
|
|
82
|
+
batchSize: 1000,
|
|
83
|
+
onCompleted: (result) => {
|
|
84
|
+
console.log('✅ 导出完成:', result.outputPath);
|
|
85
|
+
},
|
|
86
|
+
onErr: (err) => {
|
|
87
|
+
console.error('❌ 导出失败:', err.errMsg);
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
4. 查询任务进度
|
|
92
|
+
```
|
|
93
|
+
const statuses = await exportUtils.getTaskStatus({
|
|
94
|
+
taskIdList: ['export-mysql-csv-xxxx', 'export-mongo-csv-yyyy'],
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
console.log(statuses);
|
|
98
|
+
// [
|
|
99
|
+
// {
|
|
100
|
+
// taskId: 'export-mysql-csv-xxxx',
|
|
101
|
+
// total: 10000,
|
|
102
|
+
// current: 5230,
|
|
103
|
+
// progress: '52.30%',
|
|
104
|
+
// status: 'RUNNING'
|
|
105
|
+
// },
|
|
106
|
+
// ...
|
|
107
|
+
// ]
|
|
108
|
+
```
|
|
109
|
+
> 💡 进度信息存储在 Redis 中,有效期为 1 小时(TTL = 3600 秒)。
|
|
110
|
+
|
|
111
|
+
##### 📂 输出文件说明
|
|
112
|
+
- 所有导出文件均为 .csv.gz 格式(gzip 压缩的 CSV)。
|
|
113
|
+
- 示例:exports/users.csv → 实际生成 exports/users.csv.gz
|
|
114
|
+
- CSV 文件特性:
|
|
115
|
+
- 包含 UTF-8 BOM(确保 Excel 正确识别中文)
|
|
116
|
+
- 自动对包含 ,、"、换行符的字段加引号
|
|
117
|
+
|
|
118
|
+
##### 🛠 配置选项
|
|
119
|
+
> ExportUtilsOptions
|
|
120
|
+
|
|
121
|
+
|参数|类型|必填|说明
|
|
122
|
+
|-----|-----|-----|-----|
|
|
123
|
+
redisOptions|RedisOptions|✅|ioredis 配置
|
|
124
|
+
mysqlOptions|mysql2.ConnectionOptions|❌|仅 MySQL 导出时需要
|
|
125
|
+
mongoOptions|{ url: string; options?: MongoClientOptions }|❌|仅 MongoDB 导出时需要
|
|
126
|
+
|
|
127
|
+
> 字段定义(columns)
|
|
128
|
+
```
|
|
129
|
+
{
|
|
130
|
+
key: string; // 数据库字段名(支持嵌套,如 'user.name')
|
|
131
|
+
header?: string; // CSV 列标题(默认等于 key)
|
|
132
|
+
formatter?: (value: any) => any; // 值转换函数
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
##### 🧪 示例代码
|
|
137
|
+
- 项目中提供了完整示例:
|
|
138
|
+
- examples/export-mysql.ts
|
|
139
|
+
- examples/export-mongo.ts
|
|
140
|
+
|
|
141
|
+
运行方式:
|
|
142
|
+
```
|
|
143
|
+
npm run dev:mysql
|
|
144
|
+
npm run dev:mongo
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
##### 📜 开源协议
|
|
148
|
+
MIT © 501241320@qq.com
|
|
149
|
+
|
|
150
|
+
##### 🙌 注意事项
|
|
151
|
+
- 所有表名和字段名均经过安全校验(仅允许字母、数字、下划线),防止 SQL 注入。
|
|
152
|
+
- 生产环境中建议:
|
|
153
|
+
- Redis 持久化任务状态,或自行实现任务恢复机制;
|
|
154
|
+
- 控制并发导出任务数量,避免数据库压力过大。
|
|
155
|
+
##### 💡 小技巧:可使用 gunzip/7zip 解压 .csv.gz 文件,或在 Excel 中通过「数据」→「从文本/CSV」直接导入。
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sch_cat/export-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A lightweight CSV/Excel export utility for TS with TypeORM support",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"import": "./dist/index.js",
|
|
9
|
-
"types": "./dist/index.d.ts"
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
10
11
|
}
|
|
11
12
|
},
|
|
12
13
|
"main": "./dist/index.js",
|