# z-doc **Repository Path**: cpsoft13/z-doc ## Basic Information - **Project Name**: z-doc - **Description**: word模板编辑器 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-04 - **Last Updated**: 2026-06-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # z-doc 基于 Web 的合同模板编辑器,支持富文本编辑、占位符替换,一键生成 Word (.docx) 文件。 ## 特性 - **所见即所得编辑** — 基于 TipTap/ProseMirror 的 A4 页面编辑器,支持字体、字号、颜色、对齐等格式 - **占位符系统** — 在模板中插入占位符(如甲方名称、合同编号),填写参数后自动替换生成正式文档 - **表格编辑** — 插入表格,浮动气泡菜单增删行列、合并拆分单元格、切换标题行列 - **DOCX 生成** — Rust 后端将编辑内容转为标准 OOXML,导出可在 Word/WPS 中打开的 .docx 文件 - **A4 打印预览** — 真实的 A4 分页预览,支持缩放,与打印效果一致 - **文档配置** — 可调整页边距、行距、首行缩进 ## 快速开始 ### 环境要求 - **Node.js** >= 18 - **Yarn** >= 1.22 - **Rust** >= 1.75 ### 安装与启动 ```bash # 安装前端依赖 yarn install # 构建编辑器组件库 yarn workspace @z-doc/editor build # 启动开发服务(前后端同时启动) ./start.sh ``` | 服务 | 地址 | |------|------| | Demo 前端 | http://localhost:5173 | | Rust 后端 API | http://localhost:3000 | 也可分别启动: ```bash # 终端 1:启动 Rust 后端 cargo run # 终端 2:启动前端 Demo yarn workspace @z-doc/demo dev # 终端 3(可选):编辑器组件库开发模式 yarn workspace @z-doc/editor dev ``` ## 项目结构 ``` z-doc/ ├── src/ # Rust 后端 │ ├── main.rs # 入口,启动 Axum 服务 │ ├── engine/ # 文档引擎 │ │ ├── ast.rs # AST 定义(段落、表格、行内节点) │ │ ├── parser.rs # TipTap JSON → AST 解析 │ │ └── renderer.rs # AST → OOXML 渲染 │ ├── generator/ │ │ └── docx.rs # OOXML → .docx ZIP 打包 │ ├── models/mod.rs # 请求/响应数据模型 │ └── server/ │ ├── mod.rs # Axum 路由、CORS、静态文件 │ └── routes.rs # API 路由处理 ├── packages/ │ ├── editor/ # @z-doc/editor 组件库 │ │ └── src/ │ │ ├── index.ts # 导出入口 │ │ ├── types.ts # TypeScript 类型 │ │ ├── TemplateEditor.tsx # 编辑器组件 │ │ ├── Preview.tsx # A4 预览组件 │ │ ├── DocumentConfigBar.tsx # 文档配置面板 │ │ └── extensions/ # TipTap 扩展 │ │ ├── placeholder.ts # 占位符节点 │ │ └── font-size.ts # 字号/字体扩展 │ └── demo/ # Demo 应用 │ └── src/ │ ├── App.tsx # 主页面(分栏布局) │ ├── main.tsx # React 入口 │ └── index.css # 全局样式 └── docs/wiki/ # 功能设计文档 ``` ## 集成到你的项目 ### 前端 安装组件库: ```bash npm install @z-doc/editor # 或 yarn add @z-doc/editor ``` 组件 API: ```tsx import { TemplateEditor, Preview, DocumentConfigBar, DEFAULT_DOCUMENT_CONFIG, } from '@z-doc/editor'; import type { PlaceholderDef, DocumentConfig, } from '@z-doc/editor'; // 定义占位符 const placeholders: PlaceholderDef[] = [ { key: 'party_a', label: '甲方名称', defaultValue: '甲方' }, { key: 'contract_date', label: '签署日期' }, ]; // 初始模板内容(TipTap JSON) const initialDoc = { type: 'doc', content: [{ type: 'paragraph' }] }; function App() { const [document, setDocument] = useState(initialDoc); const [params, setParams] = useState>({}); const [config, setConfig] = useState(DEFAULT_DOCUMENT_CONFIG); const handleGenerate = async () => { const res = await fetch('/api/generate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ document, params, config }), }); const blob = await res.blob(); // 触发下载 const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'document.docx'; a.click(); }; return (
{/* 左侧:编辑器 */}
{/* 右侧:参数表单 + 预览 */}
); } ``` ### 后端 API **POST /api/generate** 生成 .docx 文件。 请求体 (JSON): ```json { "document": { "type": "doc", "content": [...] }, "params": { "party_a": "张三", "contract_date": "2026-01-01" }, "config": { "firstLineIndent": 2, "lineSpacing": 1.5, "pageMargins": { "top": 20, "bottom": 20, "left": 20, "right": 20 } } } ``` | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `document` | `object` | 是 | TipTap/ProseMirror JSON 文档 | | `params` | `object` | 是 | 占位符键值对,key 对应占位符的 key | | `config.firstLineIndent` | `number` | 否 | 首行缩进字符数,默认 2 | | `config.lineSpacing` | `number` | 否 | 行距倍数,默认 1.5 | | `config.pageMargins` | `object` | 否 | 页边距(mm),默认各 20 | 成功响应: - Status: `200 OK` - Content-Type: `application/vnd.openxmlformats-officedocument.wordprocessingml.document` - Body: .docx 文件二进制流 错误响应: | 状态码 | 说明 | |--------|------| | 400 | 请求格式错误 | | 500 | 文档生成失败 | ### TipTap JSON 格式 编辑器和后端之间使用标准 TipTap/ProseMirror JSON 格式。如果你使用其他编辑器,只需输出符合此格式的 JSON 即可: ```json { "type": "doc", "content": [ { "type": "paragraph", "attrs": { "textAlign": "center" }, "content": [ { "type": "text", "text": "合同编号:" }, { "type": "placeholder", "attrs": { "key": "contract_no", "label": "编号" } } ] }, { "type": "table", "content": [ { "type": "tableRow", "content": [ { "type": "tableHeader", "attrs": {}, "content": [ { "type": "paragraph", "content": [{ "type": "text", "text": "项目" }] } ] } ] } ] } ] } ``` 支持的节点类型:`doc`, `paragraph`, `heading`, `table`, `tableRow`, `tableHeader`, `tableCell`, `text`, `placeholder` 支持的文本样式(marks):`bold`, `italic`, `underline`, `strike`, `textStyle`(含 `fontSize`, `color`, `fontFamily`) ## 开发 ```bash # Rust 后端 cargo build # 编译 cargo test # 运行测试 cargo run # 启动 (localhost:3000) # 前端组件库 yarn install # 安装依赖 yarn workspace @z-doc/editor build # 构建 yarn workspace @z-doc/editor dev # 开发模式(watch) # Demo 应用 yarn workspace @z-doc/demo dev # 启动 (localhost:5173) yarn workspace @z-doc/demo build # 生产构建 ``` ### 启动脚本 ```bash # 一键启动前后端 ./start.sh # 按 Ctrl+C 停止所有服务 ``` ### 技术栈 | 层 | 技术 | |----|------| | 编辑器 | React 18 + TipTap / ProseMirror | | 预览 | TipTap generateHTML + A4 CSS 布局 | | 构建 | Vite 6 + TypeScript + yarn workspaces | | 后端 | Rust + Axum 0.7 + Tokio | | 文档生成 | 自定义 OOXML 渲染器 + ZIP 打包 | | 样式 | Tailwind CSS 3 + 自定义样式 | ## License MIT