# print-designer-web
**Repository Path**: liu_jiajun/print-designer-web
## Basic Information
- **Project Name**: print-designer-web
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-04-15
- **Last Updated**: 2026-04-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 打印模板设计器 (Print Template Designer)
可视化设计打印模板,导出 FreeMarker HTML 模板,用于 LODOP 打印控件。
## 项目概述
本项目是一个基于 Web 的打印模板可视化设计工具,主要解决以下痛点:
- **传统方式**:手写 FreeMarker HTML 模板繁琐易错
- **本方案**:拖拽式可视化设计,所见即所得,一键导出 FTL 模板
### 核心功能
| 功能 | 说明 |
|------|------|
| 📝 文本元素 | 静态文本、动态字段 `${xxx}` |
| 📊 条码元素 | CODE128、EAN13、EAN8、UPC、CODE39 |
| 📱 二维码 | QR Code,支持动态内容 |
| 📏 线条/矩形 | 装饰线条、边框矩形 |
| 📋 列表容器 | 动态明细行,支持 FreeMarker `<#list>` |
| 🖼️ 图片 | Logo、签名等图片元素 |
| 📤 导出 FTL | 一键生成 FreeMarker + LODOP 代码 |
---
## 技术架构
```
┌─────────────────────────────────────────────────────────┐
│ React 18 + TypeScript │
├─────────────────────────────────────────────────────────┤
│ Vite (构建) │ TailwindCSS (样式) │ Zustand (状态) │
├─────────────────────────────────────────────────────────┤
│ Fabric.js (画布) │
├─────────────────────────────────────────────────────────┤
│ FreeMarker 模板导出 + LODOP API │
└─────────────────────────────────────────────────────────┘
```
### 目录结构
```
src/
├── components/
│ ├── Canvas/ # 画布组件(元素渲染、拖拽、缩放)
│ ├── Toolbar/ # 工具栏(缩放、撤销、导出)
│ ├── ComponentPanel/ # 元素面板(拖入新元素)
│ ├── PropertyPanel/ # 属性面板(编辑元素属性)
│ └── Header/ # 顶部栏(模板配置)
├── store/
│ └── useTemplateStore.ts # Zustand 状态管理
├── types/
│ └── index.ts # TypeScript 类型定义
├── utils/
│ └── exportFtl.ts # FTL 模板生成器
└── hooks/ # 自定义 Hooks
```
---
## 快速开始
### 安装依赖
```bash
cd D:\print-designer\print-designer-web
npm install
```
### 启动开发服务器
```bash
npm run dev
```
访问 http://localhost:5173
### 构建生产版本
```bash
npm run build
```
输出到 `dist/` 目录。
---
## 使用指南
### 1. 创建新模板
1. 选择纸张尺寸(A4、标签、快递面单等)
2. 设置页边距
3. 从左侧组件面板拖入元素
### 2. 添加元素
| 元素类型 | 操作 |
|----------|------|
| 静态文本 | 拖入「文本」,编辑内容 |
| 动态字段 | 拖入「字段」,输入 `${orderNo}` 等 FreeMarker 表达式 |
| 条码 | 拖入「条码」,选择类型,绑定字段如 `${barcode}` |
| 列表 | 拖入「列表」,配置列、数据源如 `${order.items}` |
### 3. 编辑属性
选中元素后,右侧属性面板可编辑:
- **位置/尺寸**:left、top、width、height(单位 mm)
- **文本样式**:字体、字号、颜色、对齐
- **元素特有属性**:条码类型、列表数据源等
### 4. 导出模板
点击工具栏「导出 FTL」按钮,生成:
```html
<#-- 自动生成的 LODOP 打印模板 -->
```
---
## 元素类型详解
### TextElement(静态文本)
```typescript
{
id: string
type: 'text'
name: string
style: {
left: number // mm
top: number // mm
width: number // mm
height: number // mm
fontFamily: string
fontSize: number // pt
fontWeight: 'normal' | 'bold'
color: string // hex
textAlign: 'left' | 'center' | 'right'
}
content: string // 文本内容
}
```
### FieldElement(动态字段)
```typescript
{
id: string
type: 'field'
name: string
style: TextStyle
expression: string // FreeMarker 表达式,如 ${orderNo}
}
```
### ListElement(列表容器)
```typescript
{
id: string
type: 'list'
name: string
style: BaseStyle
iteratorName: string // 迭代变量名,如 'item'
dataSource: string // 数据源,如 'order.items'
columns: ListField[] // 列配置
headerHeight: number // 表头行高 mm
rowHeight: number // 明细行高 mm
headerBg: string // 表头背景色
zebraStripe: boolean // 斑马纹
zebraColor: string // 斑马纹颜色
}
```
---
## LODOP API 映射
| 设计器元素 | LODOP API |
|-----------|-----------|
| 文本/字段 | `ADD_PRINT_TEXT` + `SET_PRINT_STYLEA` |
| 条码 | `ADD_PRINT_BARCODE` |
| 二维码 | `ADD_PRINT_QRCODE` |
| 线条 | `ADD_PRINT_LINE` |
| 矩形 | `ADD_PRINT_RECT` |
| 图片 | `ADD_PRINT_IMAGE` |
| 列表 | `ADD_PRINT_TABLE` (内嵌 HTML + FreeMarker) |
---
## 开发指南
### 状态管理 (Zustand)
```typescript
// src/store/useTemplateStore.ts
const useTemplateStore = create((set, get) => ({
template: defaultTemplate,
selectedElementId: null,
// 元素操作
addElement: (element) => { ... },
updateElement: (id, updates) => { ... },
deleteElement: (id) => { ... },
duplicateElement: (id) => { ... },
// 选择状态
selectElement: (id) => { ... },
// 列表操作
addListColumn: (listId) => { ... },
removeListColumn: (listId, colId) => { ... },
updateListColumn: (listId, colId, updates) => { ... },
}))
```
### 添加新元素类型
1. **定义类型**:在 `types/index.ts` 添加接口
2. **创建工厂函数**:在 `store` 添加 `createDefaultXxxElement`
3. **渲染组件**:在 `Canvas/ElementRenderer` 添加 case 分支
4. **属性面板**:在 `PropertyPanel` 添加编辑区块
5. **导出逻辑**:在 `exportFtl.ts` 添加生成函数
6. **组件面板**:在 `ComponentPanel` 添加拖入按钮
---
## 已知限制
1. **列表嵌套**:暂不支持列表内再嵌套其他元素
2. **模板导入**:暂不支持解析现有 FTL 回显为设计器元素
3. **表格元素**:TableElement 类型已定义,但编辑器尚未完整支持
4. **多页模板**:列表跨页分页需手动调整
---
## 更新日志
### 2026-04-14
- ✅ 修复属性面板 `handleStyleChange` 样式覆盖 bug
- ✅ 修复选中元素后点击冒泡导致取消选中
- ✅ 修复拖拽闭包 stale 问题
- ✅ 修复 FTL 模板字符串转义问题
- ✅ 添加 image/table 元素占位渲染
---
## 许可证
MIT License