# word-render **Repository Path**: d_c_y/word-render ## Basic Information - **Project Name**: word-render - **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-03-06 - **Last Updated**: 2026-03-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Word-Render 项目实施文档生成系统 基于 Spring Boot 2.3.0.RELEASE + POI-TL 1.10.6 实现的项目实施文档自动生成系统。 ## 功能特性 - ✅ 固定表格数据填充(项目基础信息) - ✅ 动态表格生成(实施环节、工作量、人员) - ✅ 带分组的动态表格(项目环节分组展示) - ✅ 带统计行的动态表格(工作量自动汇总) - ✅ 多分组动态表格(人员按类型分组) - ✅ 单元格合并和居中对齐 - ✅ BigDecimal 精确数值计算 - ✅ RESTful API 接口 - ✅ 完整的单元测试 ## 技术栈 - JDK 11 - Spring Boot 2.3.0.RELEASE - POI-TL 1.10.6(Word 模板引擎) - Apache POI 4.1.2(由 POI-TL 依赖) - Lombok - Maven ## 项目结构 ``` word-render/ ├── src/main/java/com/example/document/ │ ├── DocumentGeneratorApplication.java # 启动类 │ ├── controller/ │ │ └── DocumentController.java # REST 控制器 │ ├── service/ │ │ └── DocumentService.java # 文档生成服务 │ ├── policy/ # 表格渲染策略 │ │ ├── PhaseTablePolicy.java # 环节表格(带分组) │ │ ├── WorkloadTablePolicy.java # 工作量表格(带统计) │ │ └── MemberTablePolicy.java # 人员表格(多分组) │ ├── model/ # 数据模型 │ │ ├── ProjectData.java # 项目数据 │ │ ├── ProjectInfoDTO.java # 项目基础信息 │ │ ├── PhaseDTO.java # 项目环节 │ │ ├── WorkloadDTO.java # 工作量 │ │ └── MemberDTO.java # 人员信息 │ └── util/ │ └── TestDataBuilder.java # 测试数据构建器 ├── src/main/resources/ │ ├── application.yml # 配置文件 │ └── templates/ │ └── 项目实施02_模板.docx # Word 模板 ├── src/test/java/ │ └── com/example/document/ │ ├── DocumentGeneratorTest.java # 基础测试 │ ├── FullDocumentTest.java # 完整文档测试 │ ├── ProjectInfoAndScheduleTest.java # 项目信息测试 │ └── ProjectInfoOnlyTest.java # 仅项目信息测试 ├── doc/ # 文档目录 │ ├── 01.需求文档.md │ ├── 02.技术方案.md │ ├── 03.代码实现.md │ ├── 04.方案-动态表格渲染方案.md │ ├── 04.方案-带统计行的动态表格实现.md │ ├── 04.方案-人员分组表格方案.md │ ├── 05.模板指南.md │ └── POI-TL使用文档.md ├── pom.xml ├── test-data.json # 测试数据 └── README.md ``` ## 快速开始 ### 1. 环境要求 - JDK 11 或更高版本 - Maven 3.6+ ### 2. 克隆项目 ```bash git clone cd word-render ``` ### 3. 编译项目 ```bash mvn clean install ``` ### 4. 运行测试 ```bash # 运行所有测试 mvn test # 运行特定测试 mvn test -Dtest=FullDocumentTest ``` 测试成功后会在 `target/` 目录生成文档文件。 ### 5. 启动应用 ```bash mvn spring-boot:run ``` 应用将在 http://localhost:8080 启动。 ## API 接口 ### 生成文档 **接口:** `POST /api/document/generate` **Content-Type:** `application/json` **请求体示例:** ```json { "projectGoal": "本项目旨在建设XX管理系统,提升业务处理效率,实现业务流程数字化转型。", "projectInfo": { "projectScale": "中型", "relatedDepartments": "各行风险管理部", "buildMethod": "新建", "buildDegree": "中等", "startDate": "2024-01-01", "endDate": "2024-12-31", "buildMode": "迭代式", "phaseCount": "二", "implementMethod": "自主开发", "provideSourceCode": "是", "dataWarehouse": "是", "hasDownstream": "否", "domain332N": "应用层", "tailorPhases": "否", "tailoredPhases": "", "tailorReason": "" }, "complexity": 2, "workloads": [ { "seq": "1", "systemName": "核心业务系统", "workload": "120.5", "cost": "50.25" }, { "seq": "2", "systemName": "数据管理系统", "workload": "80.0", "cost": "35.00" } ], "internalMembers": [ { "seq": "1", "name": "张三", "role": "项目经理", "onSite": "是", "systemName": "", "responsibility": "项目管理主责任人" } ], "outsourceMembers": [ { "seq": "10", "name": "赵六", "role": "开发人员", "onSite": "是", "systemName": "XX管理系统", "responsibility": "负责开发" } ], "externalMembers": [ { "seq": "12", "name": "孙八", "role": "技术人员", "onSite": "否", "systemName": "XX管理系统", "responsibility": "" } ], "otherNotes": "本项目采用敏捷开发模式,分两个迭代实施。" } ``` **响应:** Word 文档文件流(application/octet-stream) ### 使用 curl 测试 ```bash curl -X POST http://localhost:8080/api/document/generate \ -H "Content-Type: application/json" \ -d @test-data.json \ --output 项目实施文档.docx ``` ## 核心功能说明 ### 1. 固定表格(项目基础信息) 使用简单占位符填充固定表格: ``` {{projectScale}} {{relatedDepartments}} {{buildMethod}} ... ``` ### 2. 动态表格 - 带分组(项目环节) - 使用 `PhaseTablePolicy` 渲染 - 支持分组标题行(合并单元格) - 支持普通数据行 - 根据 `complexity` 参数生成迭代环节 **特点:** - 分组标题行:6列合并,居中显示 - 数据行:6列独立显示 - 自动序号 ### 3. 动态表格 - 带统计行(工作量) - 使用 `WorkloadTablePolicy` 渲染 - 自动计算工作量和费用汇总 - 使用 BigDecimal 精确计算 - 统计行合并前两列 **特点:** - 数据行:序号、系统名称、工作量、费用 - 统计行:合并前两列显示"汇总",后两列显示总计 ### 4. 动态表格 - 多分组(人员) - 使用 `MemberTablePolicy` 渲染 - 3个固定分组:行内人员、外包人员、行外人员 - 每组独立的数据行 **特点:** - 分组标题:6列合并 - 数据行:序号、姓名、角色、是否驻场、系统名称、职责 ## 技术要点 ### 1. DynamicTableRenderPolicy 所有动态表格策略都继承 `DynamicTableRenderPolicy`: ```java public class PhaseTablePolicy extends DynamicTableRenderPolicy { @Override public void render(XWPFTable table, Object data) throws Exception { // 实现表格渲染逻辑 } } ``` ### 2. 单元格合并 使用 Apache POI OOXML API 实现横向合并: ```java CTHMerge hMerge = tcPr.addNewHMerge(); hMerge.setVal(STMerge.RESTART); // 第一个单元格 hMerge.setVal(STMerge.CONTINUE); // 后续单元格 ``` ### 3. 单元格对齐 ```java // 垂直居中 tcPr.addNewVAlign().setVal(STVerticalJc.CENTER); // 水平居中 cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); ``` ### 4. BigDecimal 精确计算 ```java BigDecimal totalWorkload = BigDecimal.ZERO; totalWorkload = totalWorkload.add(new BigDecimal(w.getWorkload())); ``` ### 5. 表格操作 ```java // 清空表格(保留表头) for (int i = rows - 1; i > 0; i--) { table.removeRow(i); } // 创建行并确保有足够的单元格 XWPFTableRow row = table.createRow(); while (row.getTableCells().size() < 6) { row.createCell(); } ``` ## 配置说明 ### application.yml ```yaml server: port: 8080 spring: application: name: word-render servlet: multipart: max-file-size: 10MB max-request-size: 10MB logging: level: com.example.document: INFO ``` ## 文档目录 项目文档位于 `doc/` 目录: | 文档 | 说明 | |------|------| | [01.需求文档.md](doc/01.需求文档.md) | 项目需求分析 | | [02.技术方案.md](doc/02.技术方案.md) | 技术选型和架构设计 | | [03.代码实现.md](doc/03.代码实现.md) | 完整代码实现示例 | | [04.方案-动态表格渲染方案.md](doc/04.方案-动态表格渲染方案.md) | 动态表格实现方案 | | [04.方案-带统计行的动态表格实现.md](doc/04.方案-带统计行的动态表格实现.md) | 带统计行表格实现 | | [04.方案-人员分组表格方案.md](doc/04.方案-人员分组表格方案.md) | 人员分组表格实现 | | [05.模板指南.md](doc/05.模板指南.md) | Word 模板创建指南 | | [06.POI-TL使用文档.md](doc/06.POI-TL使用文档.md) | POI-TL 1.10.6 使用文档 | ## 常见问题 ### Q: 模板文件找不到 确保模板文件位于 `src/main/resources/templates/项目实施02_模板.docx`。 ### Q: 占位符不生效 检查占位符格式: - 文本占位符:`{{变量名}}` - 表格占位符:`{{@表格名}}`(必须放在表格内部) ### Q: 单元格合并不生效 POI-TL 1.10.6 需要使用 Apache POI OOXML API 手动实现单元格合并,参考 `PhaseTablePolicy` 中的 `mergeCellsHorizontal` 方法。 ### Q: 数值计算精度问题 使用 `BigDecimal` 而不是 `double` 或 `float`: ```java BigDecimal total = new BigDecimal("100.50"); total = total.add(new BigDecimal("50.25")); ``` ### Q: 中文乱码 确保: 1. 项目编码为 UTF-8 2. pom.xml 中设置 `UTF-8` ## 开发指南 ### 添加新的表格类型 1. 创建数据模型(DTO) 2. 创建渲染策略类,继承 `DynamicTableRenderPolicy` 3. 在 `DocumentService` 中注册策略 4. 在模板中添加占位符 `{{@tableName}}` ### 修改表格样式 在对应的 Policy 类中修改单元格样式、对齐方式、合并规则等。 ## 测试 项目包含完整的单元测试: ```bash # 运行所有测试 mvn test # 运行特定测试类 mvn test -Dtest=FullDocumentTest mvn test -Dtest=ProjectInfoOnlyTest ``` 测试输出文件位于 `target/` 目录。 ## 许可证 MIT License ## 贡献 欢迎提交 Issue 和 Pull Request。 ## 联系方式 如有问题,请提交 Issue。