Word文档通过poi-tl填充

wen java案例 2

本文目录导读:

Word文档通过poi-tl填充

  1. poi-tl 简介
  2. 添加依赖
  3. Word模板准备
  4. 基本用法示例
  5. 高级功能
  6. 批处理示例
  7. 异常处理
  8. 性能优化建议
  9. 注意事项

我来详细介绍如何使用poi-tl(Word模板引擎)来填充Word文档。

poi-tl 简介

poi-tl是一个基于Apache POI的Word模板引擎,通过模板标签实现Word文档的动态填充。

添加依赖

Maven

<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.12.1</version>
</dependency>

Gradle

implementation 'com.deepoove:poi-tl:1.12.1'

Word模板准备

在Word文档中使用标签语法:

基本标签

- {{@image}}             # 图片
- {{#table}}             # 表格
- {{[text]}}             # 循环块

模板示例

# 项目报告
项目名称:{{projectName}}
日期:{{date}}
{{description}}
## 成员列表
{{#members}}
姓名:{{name}},角色:{{role}},邮箱:{{email}}
{{/members}}
## 项目图片
{{@projectImage}}
## 数据统计
{{#statistics}}
| 指标 | 数值 |
|------|------|
| {{index}} | {{value}} |
{{/statistics}}

基本用法示例

1 简单文本填充

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.data.Tables;
import java.util.HashMap;
import java.util.Map;
import java.io.FileOutputStream;
public class WordFiller {
    public static void fillSimpleText() throws Exception {
        // 准备数据
        Map<String, Object> data = new HashMap<>();
        data.put("title", "项目进度报告");
        data.put("date", "2024-01-15");
        data.put("description", "这是一个示例项目描述...");
        // 渲染模板
        XWPFTemplate template = XWPFTemplate.compile("template.docx")
            .render(data);
        // 输出到文件
        template.writeAndClose(new FileOutputStream("output.docx"));
    }
}

2 复杂数据填充

public class ComplexExample {
    public static void fillComplexDocument() throws Exception {
        // 准备数据模型
        Map<String, Object> data = new HashMap<>();
        // 文本
        data.put("title", "项目报告");
        data.put("company", "ABC科技有限公司");
        // 列表数据
        List<Map<String, Object>> members = new ArrayList<>();
        Map<String, Object> member1 = new HashMap<>();
        member1.put("name", "张三");
        member1.put("role", "项目经理");
        member1.put("email", "zhangsan@example.com");
        members.add(member1);
        Map<String, Object> member2 = new HashMap<>();
        member2.put("name", "李四");
        member2.put("role", "开发工程师");
        member2.put("email", "lisi@example.com");
        members.add(member2);
        data.put("members", members);
        // 图片
        data.put("projectImage", Pictures.ofLocal("chart.png")
            .size(500, 300)
            .create());
        // 表格数据
        List<Map<String, Object>> statistics = new ArrayList<>();
        Map<String, Object> stat1 = new HashMap<>();
        stat1.put("index", "完成度");
        stat1.put("value", "75%");
        statistics.add(stat1);
        Map<String, Object> stat2 = new HashMap<>();
        stat2.put("index", "代码行数");
        stat2.put("value", "15,000");
        statistics.add(stat2);
        data.put("statistics", statistics);
        // 渲染模板
        XWPFTemplate template = XWPFTemplate.compile("template.docx")
            .render(data);
        template.writeAndClose(new FileOutputStream("output.docx"));
    }
}

高级功能

1 使用数据模型类

import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.data.style.Style;
// 定义数据模型
public class ReportData {
    private String title;
    private String date;
    private List<Member> members;
    private PictureRenderData chart;
    private TableRenderData tableData;
    // getters and setters
}
public class Member {
    private String name;
    private String role;
    private String email;
    // getters and setters
}
// 使用数据模型
public class ModelExample {
    public static void fillWithModel() throws Exception {
        ReportData reportData = new ReportData();
        reportData.setTitle("项目报告");
        // ... 设置其他属性
        XWPFTemplate template = XWPFTemplate.compile("template.docx")
            .render(reportData);
        template.writeAndClose(new FileOutputStream("output.docx"));
    }
}

2 表格高级操作

import com.deepoove.poi.data.Tables;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.TextRenderData;
public class TableExample {
    public static void createComplexTable() {
        // 创建表头
        RowRenderData header = RowRenderData.build(
            new TextRenderData("姓名"),
            new TextRenderData("年龄"),
            new TextRenderData("部门")
        );
        // 创建数据行
        RowRenderData row1 = RowRenderData.build(
            new TextRenderData("张三"),
            new TextRenderData("28"),
            new TextRenderData("技术部")
        );
        // 构建表格
        TableRenderData table = Tables.of(header, row1)
            .border(BorderStyle.DEFAULT)
            .create();
        // 添加到数据
        Map<String, Object> data = new HashMap<>();
        data.put("employeeTable", table);
    }
}

3 条件渲染

// 使用条件标签
// 模板中:{{?isImportant}}重要内容{{/isImportant}}
public class ConditionalExample {
    public static void conditionalRender() throws Exception {
        Map<String, Object> data = new HashMap<>();
        // 条件为true时显示内容
        data.put("isImportant", true);
        // 也可以使用更复杂的条件
        data.put("showWarning", false);
        XWPFTemplate template = XWPFTemplate.compile("template.docx")
            .render(data);
        template.writeAndClose(new FileOutputStream("output.docx"));
    }
}

批处理示例

public class BatchExample {
    public static void batchFill() throws Exception {
        List<Map<String, Object>> dataList = new ArrayList<>();
        // 准备多组数据
        for (int i = 0; i < 10; i++) {
            Map<String, Object> data = new HashMap<>();
            data.put("title", "报告-" + i);
            data.put("date", "2024-01-" + (15 + i));
            // 根据数据生成文件名
            String outputPath = "output/report_" + i + ".docx";
            XWPFTemplate template = XWPFTemplate.compile("template.docx")
                .render(data);
            template.writeAndClose(new FileOutputStream(outputPath));
        }
    }
}

异常处理

public class ErrorHandlingExample {
    public static void safeFill() {
        String templatePath = "template.docx";
        String outputPath = "output.docx";
        try (XWPFTemplate template = XWPFTemplate.compile(templatePath)) {
            Map<String, Object> data = new HashMap<>();
            data.put("title", "安全示例");
            template.render(data);
            template.writeAndClose(new FileOutputStream(outputPath));
            System.out.println("文档生成成功");
        } catch (IOException e) {
            System.err.println("文件操作失败: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("渲染失败: " + e.getMessage());
        }
    }
}

性能优化建议

// 1. 复用模板编译
public class TemplateCache {
    private static final Map<String, XWPFTemplate> cache = new HashMap<>();
    public static XWPFTemplate getTemplate(String path) throws Exception {
        return cache.computeIfAbsent(path, p -> {
            try {
                return XWPFTemplate.compile(p);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }
}
// 2. 使用线程池批量处理
public class BatchProcessor {
    private final ExecutorService executor = Executors.newFixedThreadPool(4);
    public void processBatch(List<Map<String, Object>> dataList) {
        List<CompletableFuture<Void>> futures = dataList.stream()
            .map(data -> CompletableFuture.runAsync(() -> {
                try {
                    processDocument(data);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }, executor))
            .collect(Collectors.toList());
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
            .join();
    }
}

注意事项

  1. 模板格式:推荐使用.docx格式
  2. 标签命名:避免使用特殊字符
  3. 图片处理:注意图片大小和格式
  4. 内存管理:大文档注意内存占用
  5. 版本兼容:确保poi-tl版本与POI版本兼容

这样就能灵活运用poi-tl进行Word文档的动态填充了。

抱歉,评论功能暂时关闭!