首页
/ EasyExcel模板填充数据问题解析与解决方案

EasyExcel模板填充数据问题解析与解决方案

2025-05-04 07:42:20作者:伍霜盼Ellen

问题背景

在使用阿里巴巴开源的EasyExcel库进行Excel操作时,开发者经常需要先创建Excel模板,然后基于模板填充数据。然而在实际开发中,很多开发者会遇到模板填充数据不成功的情况,特别是在使用内存流作为模板源时。

常见错误场景

从示例代码中可以看到,开发者尝试了以下操作:

  1. 首先通过createExcelTemplate方法创建了一个包含三列(h1,h2,h3)的Excel模板
  2. 将模板保存到ByteArrayOutputStream中,转换为字节数组
  3. 然后尝试用这个字节数组作为模板源,填充数据

但最终发现数据并没有成功填充到目标Excel文件中。

问题根本原因

经过分析,这个问题主要有两个关键点:

  1. 数据结构不匹配:EasyExcel的模板填充机制对于不同类型的数据结构有不同的处理方式。原代码中使用的是Map<String, List<Double>>结构,而EasyExcel期望的是List<Map<String,Double>>结构。

  2. 模板标记格式:在创建模板时,单元格内容应该使用{.字段名}的格式来标记填充位置,而不是直接将字段名放在单元格中。

正确解决方案

1. 修正数据结构

正确的数据结构应该是List<Map<String,Object>>,其中每个Map代表一行数据,Map中的键对应模板中的字段名,值对应要填充的数据。

public static List<Map<String,Double>> createCorrectData() {
    List<Map<String,Double>> data = new ArrayList<>();
    
    // 第一行数据
    Map<String,Double> row1 = new HashMap<>();
    row1.put("h1", 1.2);
    row1.put("h2", 1.3);
    row1.put("h3", 1.4);
    data.add(row1);
    
    // 第二行数据
    Map<String,Double> row2 = new HashMap<>();
    row2.put("h1", 2.1);
    row2.put("h2", 2.2);
    row2.put("h3", 2.3);
    data.add(row2);
    
    return data;
}

2. 修正模板创建方式

在创建模板时,应该确保单元格内容正确标记了填充位置:

public static void createCorrectTemplate(OutputStream outputStream) {
    // 创建表头
    List<List<String>> head = new ArrayList<>();
    head.add(Collections.singletonList("标题1"));
    head.add(Collections.singletonList("标题2"));
    head.add(Collections.singletonList("标题3"));
    
    // 创建模板内容 - 使用{.字段名}标记填充位置
    List<List<String>> data = new ArrayList<>();
    data.add(Arrays.asList("{.h1}", "{.h2}", "{.h3}"));
    
    EasyExcel.write(outputStream)
            .head(head)
            .sheet("Sheet1")
            .doWrite(data);
}

3. 完整的使用示例

public static void main(String[] args) throws IOException {
    // 创建模板到内存流
    ByteArrayOutputStream templateStream = new ByteArrayOutputStream();
    createCorrectTemplate(templateStream);
    byte[] templateBytes = templateStream.toByteArray();
    
    // 准备填充数据
    List<Map<String, Double>> dataToFill = createCorrectData();
    
    // 执行模板填充
    FileOutputStream outputFile = new FileOutputStream("filled_template.xlsx");
    ExcelWriter excelWriter = EasyExcel.write(outputFile)
            .withTemplate(new ByteArrayInputStream(templateBytes))
            .build();
    
    WriteSheet writeSheet = EasyExcel.writerSheet().build();
    excelWriter.fill(dataToFill, writeSheet);
    excelWriter.finish();
}

高级用法

除了基本的数据填充,EasyExcel还支持更复杂的模板操作:

  1. 多列表格填充:可以通过在模板中设置多个填充标记,然后传入多个数据集合

  2. 表格行扩展:在模板中使用$符号标记需要扩展的行,EasyExcel会自动根据数据量扩展行数

  3. 条件格式:可以在模板中设置条件格式,填充时会保留这些格式

  4. 公式支持:模板中的公式在填充后仍然有效

性能优化建议

  1. 模板缓存:对于频繁使用的模板,可以将其缓存在内存中,避免重复创建

  2. 批量处理:当数据量很大时,可以考虑分批填充,避免内存溢出

  3. 流式处理:使用EasyExcel的流式API处理大数据量场景

总结

EasyExcel的模板填充功能非常强大,但需要正确理解其数据结构和模板标记的用法。通过本文的分析和示例,开发者可以掌握模板填充的正确方法,避免常见的错误。在实际项目中,合理使用模板填充可以大大提高Excel操作的效率和代码的可维护性。

登录后查看全文
热门项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
176
260
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
854
505
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
129
182
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
254
295
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
93
15
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
331
1.08 K
HarmonyOS-ExamplesHarmonyOS-Examples
本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计!
Cangjie
397
370
note-gennote-gen
一款跨平台的 Markdown AI 笔记软件,致力于使用 AI 建立记录和写作的桥梁。
TSX
83
4
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.07 K
0
kernelkernel
deepin linux kernel
C
21
5