Skip to content

Latest commit

 

History

History
227 lines (171 loc) · 7.73 KB

File metadata and controls

227 lines (171 loc) · 7.73 KB

后端 Export 文档

仅覆盖 Go 后端:Meta(模板控制面)+ Worker(渲染/导出运行时)。不含前端编辑器说明。

1. 角色与边界

进程 入口 职责
Meta backend/cmd/meta(默认 :3010 模板 CRUD、Excel→DSL、runtime 下发;type=html 时 HTML 存 OSS
Worker backend/worker SDK / examples/worker-example(默认 :3011 拉 runtime → 进程内 DSL→HTML → PDF/Excel/Word
客户端 / 业务系统
        │
        ├─ CRUD / import-excel ──────────────► Meta (Postgres + 可选 S3)
        │
        └─ invoke / render ──────────────────► Worker
                                                 │
                                                 ├─ GET Meta /runtime
                                                 ├─ dslrender.Render(DSL, data) → HTML
                                                 └─ export.* → pdf | excel | word

原则

  • type=report:模板唯一可信源是 dslJson;HTML 只是运行时产物,不回写库。
  • Worker 不访问 S3type=html 时 Meta 返回 templateUrl,Worker 用 HTTP GET。
  • 导出格式在请求时指定,不存模板上。

2. 本地启动

cp .env.example .env
make docker-up          # Postgres + rustfs(S3)
make run-meta           # :3010
make run-worker         # :3011
变量 用途 默认
PORT Meta 端口 3010
LOWCODE_EXPORT_POSTGRES_DSN Meta DB .env.example
LOWCODE_EXPORT_S3_* Meta 存 type=html 模板体 rustfs 本地默认
LOWCODE_EXPORT_META_URL Worker → Meta http://127.0.0.1:3010
LOWCODE_EXPORT_WORKER_LISTEN Worker 监听 :3011
LOWCODE_EXPORT_LOG_LEVEL Worker 日志 info
PDF_FONT_FILE PDF 中文 .ttf(可选) macOS 可自动找 Arial Unicode

3. Meta API

Base:http://127.0.0.1:3010

方法 路径 说明
GET /healthz { ok, role: "meta" }
GET /api/formats { formats: ["pdf","excel","word"] }
GET /api/templates 模板列表
GET /api/templates/get?id= 模板详情(含 dslJson / html
POST/PUT /api/templates/save 保存;name 必填;report 用 dslJson
DELETE /api/templates/delete?id= 删除
GET /api/templates/{id}/runtime Worker 用:DSL 或 templateUrl + etag
POST /api/templates/import-excel multipart file{ dsl, name, sheetNames }(不落库)
POST /api/preview 兼容预览(HTML Mustache 或透传)

保存模板体(节选)

{
  "id": "optional-uuid",
  "name": "report_{{year}}_{{month}}",
  "type": "report",
  "group": "household",
  "dslJson": { "id": "page_1", "type": "page", "props": {}, "children": [] }
}
  • name 可含 Mustache 变量;导出文件名在 Worker 侧用业务 data 解析(如 report_2016_08.pdf)。
  • 入站仍可接受遗留字段 fields 作为 dslJson 别名;响应不再回写 fields

Runtime 响应

{
  "id": "...",
  "name": "...",
  "type": "report",
  "etag": "...",
  "dslJson": { },
  "templateUrl": ""
}

type=html 时主要用 templateUrl(或偶发 inline html)。

4. Worker API

Base:http://127.0.0.1:3011

方法 路径 说明
GET /healthz { ok, role: "worker" }
GET /api/formats 同 Meta
POST /api/render/html DSL + bizData → HTML(JSON)
POST /api/render/pdf 已渲染 HTML → PDF 文件流
POST /api/templates/{id}/invoke 完整导出(推荐)
POST /api/export { templateId, format, data },等同 invoke

4.1 渲染 HTML

POST /api/render/html
Content-Type: application/json

{ "templateDsl": { ... }, "bizData": { ... } }
{ "code": 0, "data": { "html": "<!DOCTYPE html>..." } }

实现:internal/dslrender.Render

4.2 完整导出(invoke)

POST /api/templates/{id}/invoke
Content-Type: application/json

{ "format": "pdf", "data": { "person": { "name": "张三" }, "year": "2016", "month": "08" } }

响应:文件字节流。

Header 含义
Content-Type pdf / xlsx / docx MIME
Content-Disposition attachment; filename="..."(名称已解析变量)
X-Export-Etag 模板 etag
X-Export-Template 模板 id
X-Export-Duration-Ms 耗时

流水线

  1. GET {META}/api/templates/{id}/runtime
  2. type=report|tmagicdslrender.Render(dslJson, data) → HTML
    type=html:拉取 templateUrl / Mustache 渲染 → HTML
  3. export.ExportRenderedHTML(format, html, data) → 文件

4.3 curl 示例

curl -X POST "http://127.0.0.1:3011/api/templates/<id>/invoke" \
  -H 'Content-Type: application/json' \
  -d '{"format":"excel","data":{"year":"2016","month":"08","person":{"name":"张三"}}}' \
  -o out.xlsx

5. DSL → HTML(dslrender)

包:backend/internal/dslrender

顶层 page(建议 A4:794×1123),子节点 children + layout{left,top,width,height}

type 说明
text 文案;props.text 支持 {{a.b}}fontSize / fontWeight / color / textAlign
image props.src / url,可变量
divider 分割线;长度=layout.width,粗细=layout.heightprops.color
report-sheet 网格;sheetData + loops

report-sheet

  • sheetData:LuckySheet 兼容
    row / column / celldata / merge / columnlen / rowlen / borderInfo / images / hyperlink
  • loops[]sourceitemNamestartRowrowCount(按数组展开原型行)
  • 单元格:文本 / {{item.x}};图片 URL、{{logoUrl}}tp:"img"![alt](url)<img>
  • 单元格样式:bl 加粗、fc 颜色、bg 背景;borderInfo → td 边框

6. HTML → 文件(export)

包:backend/internal/export

format 引擎 行为摘要
pdf gofpdf + UTF-8 中文字体 按文档块输出文本/表格/分割线/图片;保留加粗与颜色、单元格边框
excel excelize 文本块 + 表格(样式/边框);图片尽量嵌入
word 简易 OOXML 由 HTML 结构生成

公共步骤:

  1. 从 HTML 抽文档块(report-texttablereport-divider)与图片
  2. 解析内联 color / font-weight / border-*
  3. ResolveExportFilename(template.Name, data) → 安全文件名

PDF 字体AddUTF8FontFromBytes;候选路径含 PDF_FONT_FILE、系统 Arial Unicode / Noto Sans SC。缺字体会直接报错(避免中文乱码静默失败)。

7. 嵌入 Worker SDK

import "github.com/solat/lowcode-export/worker"

w, err := worker.New(worker.ConfigFromEnv())
// 或 worker.New(cfg, worker.WithLogger(log))

_ = w.Run(ctx)
// 或 mux.Handle("/", w.Handler())

环境:至少配置 LOWCODE_EXPORT_META_URL。详见 backend/examples/worker-example

8. 包索引

路径 职责
backend/cmd/meta Meta 进程
backend/worker 可嵌入 Worker SDK
backend/internal/dslrender DSL → HTML
backend/internal/export HTML → PDF/Excel/Word
backend/internal/excelimport Excel → DSL(Meta)
backend/internal/store Postgres 模板 + OSS HTML
backend/internal/handlers Meta / Worker HTTP
backend/internal/metaclient Worker 调 Meta
backend/internal/models DTO / 格式常量

9. 与架构 PRD 的关系

整体产品边界、DSL 与旧 tmagic 差异见 prd-architecture.md。本文只展开 后端导出调用方式与实现落点