将 Excel 文件导入到 PostgreSQL 或 Supabase,支持:
- 驱动二选一(环境变量):PostgreSQL(连接串)或 Supabase(纯 REST:URL + API Key);前端从当前驱动拉取 tables/columns,create、insert、upsert 均在当前驱动下执行
- 一个 Excel 表对应多张数据库表(例如:订单商品列表 → 订单表 + 商品表)
- 多种导入模式:创建(Insert)、更新(Update)、UPSERT
- Step 5 Mapping & Transformation(Hevo-style):核对列映射;每列可选转换(trim / 大写 / 小写 / 默认值);表不存在时自动建表
- 导入模板:保存/加载映射与转换配置
- 前端示例:纯 HTML,显示当前驱动,并从该驱动拉取 tables、columns 并执行导入
- 后端:Golang(Go 1.21+)、PostgreSQL(pgx)、Excel 解析(excelize)
- 前端:单页 HTML + 原生 JS,由 Go 提供静态文件与 API
- 安装 Go 1.21+
- 本地 PostgreSQL(或使用
DATABASE_URL指向已有库)
复制环境变量示例并修改:
cp .env.example .env
# 编辑 .envPostgres 驱动:
export DRIVER=postgres
export DATABASE_URL="postgresql://user:password@localhost:5432/your_db?sslmode=disable"
export PORT=3001Supabase 驱动:(纯 REST API,无需 Postgres 连接串。详见 docs/SUPABASE.md)
export DRIVER=supabase
export SUPABASE_URL="https://你的项目ref.supabase.co"
export SUPABASE_SERVICE_ROLE_KEY="你的 service_role key"
export PORT=3001未设置 DRIVER 时默认为 postgres;未设置 DATABASE_URL 时 Postgres 默认连接 localhost:5432/postgres。
在目标库中创建表,例如订单+商品:
CREATE TABLE IF NOT EXISTS orders (
id SERIAL PRIMARY KEY,
order_no TEXT,
amount NUMERIC(12,2)
);
CREATE TABLE IF NOT EXISTS products (
id SERIAL PRIMARY KEY,
sku TEXT UNIQUE,
name TEXT,
price NUMERIC(12,2)
);在项目根目录执行(推荐使用 Makefile):
make run
# 或
make start若有 .env 文件,make run 会自动加载其中的环境变量。其他命令:
make build # 编译到 bin/server
make build-run # 编译并运行
make clean # 删除 bin/
make check # 仅编译检查
make setup-db # 执行 scripts/init-db.sql(需已设置 DATABASE_URL 和 psql)也可直接使用 Go:
go run ./cmd/server
# 或
go build -o bin/server ./cmd/server && ./bin/server浏览器打开:http://localhost:3001
- 当前驱动:页面会显示当前驱动(PostgreSQL 或 Supabase),由服务端环境变量决定;tables、columns 的拉取以及 create/insert/upsert 均在该驱动下执行。
- 上传 Excel:选择 .xlsx 文件,点击「上传并解析」。
- 选择 Sheet:在 Tab 中切换要配置的 Sheet。
- Mapping & Transformation:
- 可为当前 Sheet 配置多张目标表(点击「添加一张表的映射」)。
- 每张表:目标表、模式(创建/更新/UPSERT)、列映射(Excel 列 → 数据库列)、每列转换(无 / trim / 大写 / 小写 / 默认值)、表不存在时自动创建(仅 Postgres 驱动支持;Supabase REST 下会忽略)。
- 可「保存为模板」或「加载」已有模板;「自动分析建议」会根据表头猜测表与列。
- 执行导入:点击「执行导入」,在当前驱动下执行,查看新增/更新条数。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/config |
当前驱动({ "driver": "postgres" | "supabase" }) |
| POST | /api/upload |
上传 Excel,返回 fileKey、sheetNames、sheets(表头等) |
| GET | /api/tables |
从当前 driver 拉取表列表(schema + table) |
| GET | /api/columns?schema=&table= |
从当前 driver 拉取指定表的列 |
| POST | /api/import/execute |
在当前 driver 下执行导入(body: { "fileKey", "template" },template 含 columnMap、transforms、autoCreateTable) |
| GET | /api/templates |
模板列表 |
| GET | /api/templates/get?id= |
获取单个模板 |
| POST | /api/templates/save |
保存模板(body: 模板 JSON) |
| 变量 | 说明 | 默认 |
|---|---|---|
DRIVER |
驱动二选一:postgres | supabase |
postgres |
DATABASE_URL |
Postgres 连接串(DRIVER=postgres 时使用;也可用 POSTGRES_DATABASE_URL) |
postgresql://localhost:5432/postgres?sslmode=disable |
SUPABASE_URL |
Supabase 项目 URL(DRIVER=supabase 时必填,如 https://xxx.supabase.co) |
无 |
SUPABASE_SERVICE_ROLE_KEY |
Service role key(推荐);或使用 SUPABASE_ANON_KEY |
无 |
PORT |
HTTP 端口 | 3001 |
UPLOAD_DIR |
上传/临时目录 | 系统临时目录下的 excel-import |
TEMPLATES_PATH |
模板 JSON 文件路径 | UPLOAD_DIR/templates.json |
STATIC_DIR |
前端静态文件目录 | static(相对当前工作目录) |
.
├── cmd/server/main.go # 程序入口、从 destination.Store 取当前 Driver
├── internal/
│ ├── destination/ # 目标存储抽象:Driver 接口 + Store 注册
│ │ ├── driver.go # Driver 接口(ListTables/ListColumns/Exec*)
│ │ ├── store.go # Register(name, factory)、NewStore() 按 DRIVER 选驱动
│ │ ├── postgres.go # Store driver:Postgres(db)
│ │ └── supabase.go # Store driver:Supabase REST
│ ├── db/ # Postgres 实现(*db.DB 实现 destination.Driver)
│ ├── supabase/ # Supabase REST 实现(*Client 实现 destination.Driver)
│ ├── excel/ # Excel 解析(excelize)
│ ├── importengine/ # 导入逻辑(依赖 destination.Driver)
│ ├── handlers/ # HTTP,使用 destination.Store
│ └── models/ # 请求/模板/转换数据结构
├── static/
│ └── index.html # 前端
├── go.mod
├── .env.example
└── README.md
扩展新目标存储:实现 destination.Driver 接口,在 init() 中 destination.Register("名称", NewXxxDriver),并配置对应环境变量即可。
MIT