README.md•7.88 kB
# JXLS Excel模板生成MCP服务端
一个基于MCP(Model Context Protocol)协议的服务端,用于生成符合JXLS规范的Excel模板文件。
## 功能特性
- 🎯 **JXLS规范支持**: 生成包含`jx:area()`和`jx:each()`批注的Excel模板
- 📊 **多数据格式**: 支持JSON对象和数组两种数据格式
- 🔧 **MCP协议**: 完整的MCP协议实现,支持stdio通信模式
- ✅ **参数验证**: 严格的输入参数验证和错误处理
- 🛡️ **安全性**: 文件路径安全检查,防止路径遍历攻击
- 📝 **类型安全**: 基于Pydantic的类型安全数据模型
## 快速开始
### 安装依赖
```bash
uv sync
```
### 基本使用
#### JSON格式示例
```python
from jxls_mcp.models import GenerateTemplateRequest, DataStruct, DataField
from jxls_mcp.services import TemplateGenerator
# 创建数据结构
data_struct = DataStruct(
collectName="employees",
itemVariable="employee",
dataFields=[
DataField(name="姓名", field="name"),
DataField(name="年龄", field="age"),
DataField(name="部门", field="department")
]
)
# 创建请求
request = GenerateTemplateRequest(
templateName="employee_report",
dataStruct=data_struct,
dataFormat="json"
)
# 生成模板
generator = TemplateGenerator()
response = generator.generate_template(request)
print(f"生成成功: {response.success}")
print(f"文件路径: {response.templatePath}")
```
#### 数组格式示例
```python
# 创建数组格式数据结构
data_struct = DataStruct(
collectName="dataList",
itemVariable="row",
dataFields=[
DataField(name="列1", index=0),
DataField(name="列2", index=1),
DataField(name="列3", index=2)
]
)
# 创建请求
request = GenerateTemplateRequest(
templateName="data_export",
dataStruct=data_struct,
dataFormat="array"
)
# 生成模板
generator = TemplateGenerator()
response = generator.generate_template(request)
```
#### 带有不绑定列的示例
```python
# 创建包含绑定和不绑定列的数据结构
data_struct = DataStruct(
collectName="employees",
itemVariable="employee",
dataFields=[
DataField(name="序号"), # 不绑定数据,留空供手工填写
DataField(name="姓名", field="name"), # 绑定到name字段
DataField(name="年龄", field="age"), # 绑定到age字段
DataField(name="部门", field="department"), # 绑定到department字段
DataField(name="备注") # 不绑定数据,留空供手工填写
]
)
# 创建请求
request = GenerateTemplateRequest(
templateName="employee_with_static_columns",
dataStruct=data_struct,
dataFormat="json"
)
# 生成模板
generator = TemplateGenerator()
response = generator.generate_template(request)
# 生成的Excel模板将包含:
# 第1行:序号 | 姓名 | 年龄 | 部门 | 备注
# 第2行:(空) | ${employee.name} | ${employee.age} | ${employee.department} | (空)
```
### MCP服务器模式
启动MCP服务器:
```bash
uv run jxls-mcp-server
```
或者作为MCP工具调用:
```json
{
"name": "generateJxlsTemplate",
"arguments": {
"templateName": "sales_report",
"dataStruct": {
"collectName": "sales",
"itemVariable": "sale",
"dataFields": [
{"name": "产品名称", "field": "product"},
{"name": "销售额", "field": "amount"},
{"name": "销售日期", "field": "date"}
]
},
"dataFormat": "json",
"sampleData": [
{"product": "产品A", "amount": 1000, "date": "2024-01-01"}
]
}
}
```
## 数据结构定义
### DataStruct参数
```json
{
"collectName": "data",
"itemVariable": "item",
"dataFields": [
{
"name": "列标题",
"field": "fieldName",
"index": 0
}
]
}
```
**说明**:
- `collectName`: 集合变量名称,用于JXLS批注中的items参数
- `itemVariable`: 循环项变量名,用于JXLS批注中的var参数
- `dataFields`: 字段定义数组
- `name`: 列标题显示名称(必需)
- `field`: JSON格式时的字段名(可选,为空表示该列不绑定数据)
- `index`: 数组格式时的索引位置(可选,为空表示该列不绑定数据)
**新特性 - 不绑定数据的列**:
从v1.1.0开始,支持创建不绑定数据的列。当`field`(JSON格式)或`index`(数组格式)为空时,该列在数据行中将保持为空单元格,不生成JXLS表达式。这对于以下场景非常有用:
- **静态列**:如序号、固定文本说明等
- **手工填写列**:如备注、审批意见等需要用户手动填写的列
- **计算列**:由Excel公式计算得出的列
## 生成的Excel模板
### JSON格式模板示例
```
A1: 姓名 B1: 年龄 C1: 城市
A2: ${item.name} B2: ${item.age} C2: ${item.city}
```
**JXLS批注**:
- A1单元格: `jx:area(lastCell="C2")`
- A2单元格: `jx:each(items="data" var="item" lastCell="C2")`
### 数组格式模板示例
```
A1: 列1 B1: 列2 C1: 列3
A2: ${item[0]} B2: ${item[1]} C2: ${item[2]}
```
**JXLS批注**:
- A1单元格: `jx:area(lastCell="C2")`
- A2单元格: `jx:each(items="data" var="item" lastCell="C2")`
## API参考
### generateJxlsTemplate工具
#### 输入参数
| 参数名 | 类型 | 必需 | 描述 |
|--------|------|------|------|
| templateName | string | 是 | 模板文件名称 |
| dataStruct | object | 是 | 数据结构定义 |
| dataFormat | string | 是 | 数据格式类型 ("json" 或 "array") |
| sampleData | array | 否 | 示例数据(用于验证) |
| outputPath | string | 否 | 导出文件路径 |
#### outputPath 参数详解
`outputPath` 参数支持多种路径格式,系统会根据路径特征自动判断处理方式:
**1. 相对路径支持**
```json
{
"outputPath": "templates/my_template.xlsx" // 使用指定文件名
}
```
**2. 绝对路径支持**
```json
{
"outputPath": "C:/Users/username/Documents/my_template.xlsx" // 使用指定文件名
}
```
**3. 目录路径(自动生成文件名)**
```json
{
"outputPath": "C:/Users/username/Documents/templates" // 自动生成: templateName_timestamp.xlsx
}
```
**4. 自定义文件名**
```json
{
"outputPath": "reports/sales_report" // 自动添加.xlsx扩展名
}
```
**路径处理规则**:
- 如果路径不包含扩展名且不存在,则视为目录路径,使用 `templateName_timestamp.xlsx` 格式生成文件名
- 如果路径包含文件名(有扩展名或存在同名文件),则直接使用该文件名
- 如果文件名没有 `.xlsx` 扩展名,系统会自动添加
- 系统会自动创建不存在的目录
- 保持路径遍历攻击防护(不允许包含 `..`)
#### 输出结果
```json
{
"success": true,
"templatePath": "/path/to/generated/template.xlsx",
"message": "JXLS模板生成成功",
"jxlsAnnotations": {
"area": "jx:area(lastCell=\"C2\")",
"each": "jx:each(items=\"data\" var=\"item\" lastCell=\"C2\")"
},
"dataStruct": {
"collectName": "data",
"itemVariable": "item",
"columnCount": 3,
"lastCell": "C2"
}
}
```
## 开发
### 运行测试
```bash
pytest
```
### 代码格式化
```bash
black src/ tests/
isort src/ tests/
```
### 类型检查
```bash
mypy src/
```
## 环境变量
- `JXLS_OUTPUT_DIR`: 模板输出目录,默认为 `./templates`
## 许可证
MIT License
## 贡献
欢迎提交Issue和Pull Request!
## 更新日志
### v1.1.0
- 新增:支持不绑定数据的列
- 允许field和index都为空,表示该列不需要数据绑定
- 适用于静态列、手工填写列、计算列等场景
- 向后兼容,不影响现有使用方式
### v1.0.0
- 初始版本发布
- 支持JXLS规范的Excel模板生成
- 完整的MCP协议实现
- JSON和数组两种数据格式支持