# JXLS Excel模板生成MCP服务端开发计划
## 1. 项目概述
### 1.1 项目目标
基于更新的需求文档,开发一个支持JXLS规范的Excel模板生成MCP服务端,核心特性包括:
- 统一的dataStruct参数结构
- 支持JSON和数组两种数据格式
- 标准化的JXLS批注生成
- 完整的MCP协议支持
### 1.2 技术栈
- **语言**: Python 3.10+
- **MCP框架**: MCP Python SDK
- **Excel处理**: openpyxl
- **数据验证**: pydantic
- **JSON处理**: 标准json库
## 2. 开发阶段规划
### 阶段一:项目初始化与基础设施 (Week 1)
#### 2.1 项目结构搭建
```
jxls-mcp-server/
├── src/
│ ├── jxls_mcp/
│ │ ├── __init__.py
│ │ ├── server.py # MCP服务器主入口
│ │ ├── models/
│ │ │ ├── __init__.py
│ │ │ ├── request.py # 请求模型定义
│ │ │ └── response.py # 响应模型定义
│ │ ├── services/
│ │ │ ├── __init__.py
│ │ │ ├── template_generator.py # 模板生成服务
│ │ │ └── validator.py # 参数验证服务
│ │ └── utils/
│ │ ├── __init__.py
│ │ ├── excel_helper.py # Excel操作工具
│ │ └── jxls_helper.py # JXLS批注工具
├── tests/
│ ├── __init__.py
│ ├── test_models.py
│ ├── test_services.py
│ └── test_integration.py
├── templates/ # 生成的模板输出目录
├── examples/ # 示例文件
├── docs/
├── pyproject.toml
├── README.md
└── .gitignore
```
#### 2.2 环境配置
- 配置pyproject.toml依赖管理
- 设置开发环境和测试环境
- 配置代码格式化和lint工具
### 阶段二:核心数据模型实现 (Week 1-2)
#### 2.3 Pydantic模型定义
**DataField模型**:
```python
class DataField(BaseModel):
name: str = Field(..., description="列标题显示名称")
field: Optional[str] = Field(None, description="JSON格式字段名")
index: Optional[int] = Field(None, description="数组格式索引位置")
@model_validator(mode='after')
def validate_field_or_index(self):
if not self.field and self.index is None:
raise ValueError("field和index至少需要提供一个")
return self
```
**DataStruct模型**:
```python
class DataStruct(BaseModel):
collectName: str = Field(..., description="集合变量名称")
itemVariable: str = Field(..., description="循环项变量名")
dataFields: List[DataField] = Field(..., min_items=1, description="字段定义数组")
```
**GenerateTemplateRequest模型**:
```python
class GenerateTemplateRequest(BaseModel):
templateName: str = Field(..., description="模板文件名称")
dataStruct: DataStruct = Field(..., description="数据结构定义")
dataFormat: Literal["json", "array"] = Field(..., description="数据格式类型")
sampleData: Optional[List[Any]] = Field(None, description="示例数据")
outputPath: Optional[str] = Field(None, description="导出文件路径")
```
#### 2.4 响应模型
```python
class GenerateTemplateResponse(BaseModel):
success: bool
templatePath: Optional[str] = None
message: str
error: Optional[str] = None
details: Optional[str] = None
```
### 阶段三:核心业务逻辑实现 (Week 2-3)
#### 2.5 参数验证服务 (validator.py)
```python
class ParameterValidator:
def validate_data_struct(self, data_struct: DataStruct, data_format: str) -> None:
"""验证数据结构与格式匹配"""
def validate_sample_data(self, sample_data: List[Any], data_struct: DataStruct, data_format: str) -> None:
"""验证示例数据格式"""
def validate_template_name(self, template_name: str) -> None:
"""验证模板名称安全性"""
```
#### 2.6 Excel操作工具 (excel_helper.py)
```python
class ExcelHelper:
def create_workbook(self) -> Workbook:
"""创建新的Excel工作簿"""
def add_headers(self, worksheet: Worksheet, headers: List[str]) -> None:
"""添加列标题行"""
def add_data_row(self, worksheet: Worksheet, data_struct: DataStruct, data_format: str, row: int) -> None:
"""添加数据行模板"""
def save_workbook(self, workbook: Workbook, file_path: str) -> None:
"""保存工作簿"""
```
#### 2.7 JXLS批注工具 (jxls_helper.py)
```python
class JxlsHelper:
def create_area_annotation(self, last_cell: str) -> str:
"""创建jx:area批注"""
def create_each_annotation(self, items: str, var: str, last_cell: str) -> str:
"""创建jx:each批注"""
def add_annotations_to_cell(self, worksheet: Worksheet, cell: str, annotations: List[str]) -> None:
"""向单元格添加批注"""
def calculate_last_cell(self, column_count: int, row: int) -> str:
"""计算lastCell坐标"""
```
#### 2.8 模板生成服务 (template_generator.py)
```python
class TemplateGenerator:
def __init__(self):
self.excel_helper = ExcelHelper()
self.jxls_helper = JxlsHelper()
self.validator = ParameterValidator()
def generate_template(self, request: GenerateTemplateRequest) -> GenerateTemplateResponse:
"""主要模板生成方法"""
def _create_json_template(self, request: GenerateTemplateRequest) -> str:
"""创建JSON格式模板"""
def _create_array_template(self, request: GenerateTemplateRequest) -> str:
"""创建数组格式模板"""
def _generate_file_path(self, template_name: str, output_path: Optional[str]) -> str:
"""生成文件路径"""
```
### 阶段四:MCP服务器实现 (Week 3-4)
#### 2.9 MCP服务器主体 (server.py)
```python
class JxlsTemplateServer:
def __init__(self):
self.template_generator = TemplateGenerator()
async def handle_generate_template(self, arguments: dict) -> dict:
"""处理generateJxlsTemplate工具调用"""
def register_tools(self) -> List[dict]:
"""注册MCP工具"""
async def run_stdio(self):
"""运行stdio模式"""
def get_server_info(self) -> dict:
"""获取服务器信息"""
```
#### 2.10 工具定义
```python
GENERATE_TEMPLATE_TOOL = {
"name": "generateJxlsTemplate",
"description": "根据输入参数生成符合JXLS规范的Excel模板文件",
"inputSchema": {
"type": "object",
"properties": {
"templateName": {
"type": "string",
"description": "模板文件名称"
},
"dataStruct": {
"type": "object",
"description": "数据结构定义",
"properties": {
"collectName": {"type": "string"},
"itemVariable": {"type": "string"},
"dataFields": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"field": {"type": "string"},
"index": {"type": "integer"}
}
}
}
}
},
"dataFormat": {
"type": "string",
"enum": ["json", "array"]
},
"sampleData": {
"type": "array",
"description": "示例数据(可选)"
},
"outputPath": {
"type": "string",
"description": "导出文件路径(可选)"
}
},
"required": ["templateName", "dataStruct", "dataFormat"]
}
}
```
### 阶段五:测试实现 (Week 4-5)
#### 2.11 单元测试
- **test_models.py**: 测试Pydantic模型验证
- **test_validator.py**: 测试参数验证逻辑
- **test_excel_helper.py**: 测试Excel操作功能
- **test_jxls_helper.py**: 测试JXLS批注生成
- **test_template_generator.py**: 测试模板生成服务
#### 2.12 集成测试
- **test_mcp_integration.py**: 测试MCP协议通信
- **test_end_to_end.py**: 端到端功能测试
- **test_error_handling.py**: 错误处理测试
#### 2.13 测试用例设计
```python
# JSON格式测试用例
json_test_case = {
"templateName": "employee_report",
"dataStruct": {
"collectName": "employees",
"itemVariable": "employee",
"dataFields": [
{"name": "姓名", "field": "name"},
{"name": "年龄", "field": "age"},
{"name": "部门", "field": "department"}
]
},
"dataFormat": "json",
"sampleData": [
{"name": "张三", "age": 25, "department": "技术部"},
{"name": "李四", "age": 30, "department": "销售部"}
]
}
# 数组格式测试用例
array_test_case = {
"templateName": "data_export",
"dataStruct": {
"collectName": "dataList",
"itemVariable": "row",
"dataFields": [
{"name": "列1", "index": 0},
{"name": "列2", "index": 1},
{"name": "列3", "index": 2}
]
},
"dataFormat": "array",
"sampleData": [
["值1", "值2", "值3"],
["值4", "值5", "值6"]
]
}
```
### 阶段六:文档与部署 (Week 5-6)
#### 2.14 文档编写
- API参考文档
- 使用指南和示例
- 开发者文档
- 故障排除指南
#### 2.15 部署配置
- Docker容器化
- 启动脚本编写
- 环境配置文档
## 3. 详细实现要点
### 3.1 关键技术实现
#### 3.1.1 JXLS批注生成策略
```python
def generate_jxls_annotations(self, data_struct: DataStruct, column_count: int):
"""生成JXLS批注"""
last_cell = self.jxls_helper.calculate_last_cell(column_count, 2)
# A1单元格添加area批注
area_annotation = self.jxls_helper.create_area_annotation(last_cell)
# A2单元格添加each批注
each_annotation = self.jxls_helper.create_each_annotation(
items=data_struct.collectName,
var=data_struct.itemVariable,
last_cell=last_cell
)
return area_annotation, each_annotation
```
#### 3.1.2 动态数据表达式生成
```python
def generate_data_expressions(self, data_struct: DataStruct, data_format: str) -> List[str]:
"""根据数据格式生成表达式"""
expressions = []
if data_format == "json":
for field in data_struct.dataFields:
expressions.append(f"${{{data_struct.itemVariable}.{field.field}}}")
else: # array
for field in data_struct.dataFields:
expressions.append(f"${{{data_struct.itemVariable}[{field.index}]}}")
return expressions
```
#### 3.1.3 参数验证逻辑
```python
def validate_data_format_consistency(self, data_struct: DataStruct, data_format: str):
"""验证数据格式一致性"""
if data_format == "json":
for field in data_struct.dataFields:
if not field.field:
raise ValueError(f"JSON格式时字段'{field.name}'必须提供field属性")
elif data_format == "array":
for field in data_struct.dataFields:
if field.index is None:
raise ValueError(f"数组格式时字段'{field.name}'必须提供index属性")
```
### 3.2 错误处理策略
#### 3.2.1 参数验证错误
- 缺失必需参数
- 数据格式不匹配
- 无效的文件名
- 路径安全检查
#### 3.2.2 文件操作错误
- 文件创建失败
- 权限不足
- 磁盘空间不足
- 路径不存在
#### 3.2.3 MCP协议错误
- 工具调用参数错误
- 响应格式错误
- 通信中断处理
## 4. 里程碑时间表
| 阶段 | 任务 | 预计完成时间 | 交付物 |
|------|------|-------------|--------|
| 1 | 项目初始化 | Week 1 | 项目结构、环境配置 |
| 2 | 数据模型 | Week 1-2 | Pydantic模型定义 |
| 3 | 核心逻辑 | Week 2-3 | 业务服务实现 |
| 4 | MCP服务器 | Week 3-4 | MCP协议实现 |
| 5 | 测试 | Week 4-5 | 完整测试套件 |
| 6 | 文档部署 | Week 5-6 | 文档、部署配置 |
## 5. 风险评估与应对
### 5.1 技术风险
- **JXLS批注兼容性**: 通过测试验证批注格式正确性
- **Excel文件格式**: 使用openpyxl确保格式兼容
- **MCP协议实现**: 参考官方SDK文档和示例
### 5.2 进度风险
- **复杂度低估**: 预留20%缓冲时间
- **依赖问题**: 提前验证关键依赖库
- **测试覆盖**: 确保核心功能100%测试覆盖
## 6. 质量保证
### 6.1 代码质量
- 使用type hints和pydantic确保类型安全
- 遵循PEP 8代码规范
- 单元测试覆盖率≥90%
- 集成测试覆盖核心用例
### 6.2 性能要求
- 模板生成时间<1秒
- 内存使用<100MB
- 支持并发请求处理
### 6.3 安全要求
- 输入参数严格验证
- 文件路径安全检查
- 错误信息不泄露敏感信息
---
**文档版本**: 1.0
**创建日期**: 2025-01-30
**负责人**: 开发团队
**状态**: 待执行