博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Apache POI实现Excel文件导出
阅读量:4186 次
发布时间:2019-05-26

本文共 3080 字,大约阅读时间需要 10 分钟。

文章转载地址:

最近开发excel导入导出功能,使用的是Apache的POI技术

POI提供了很多对Microsoft Office的功能,本文仅仅讲解POI的Excel导出功能

版本如下:

   
org.apache.poi
   
poi-ooxml-schemas
    
3.10-FINAL
 
   
org.apache.poi
   
poi-ooxml
    
3.10-FINAL
 
   
org.apache.poi
   
poi
    
3.10-FINAL

几个关键对象: 

HSSFWorkbook类就是一个excel文件 
这里写图片描述

一个excel文件有很多页,HSSFSheet就是一个页

这里写图片描述

一页有很多行,HSSFRow代表一行 

这里写图片描述

一行有很多格,HSSFCell代表一个单元格 

这里写图片描述

前辈大牛充分发挥了Java的抽象,封装,继承,多态,写出了如此优雅的代码….尔等渣渣只能膜拜

我的想法是利用反射获取JavaBean的字段和值,写一个通用的Excel工具类,并可以在客户端选择保存路径,代码分为几个部分讲解: 

第一部分:

//反射,获取类对象        Object obj = list.get(0);        Class clazz = obj.getClass();        //创建excel工作簿        HSSFWorkbook wb = new HSSFWorkbook();        //创建页 ,指定页的名字就是表名,excel有很多页        HSSFSheet sheet = wb.createSheet(clazz.getSimpleName());        //设置单元格样式,居中显示        HSSFCellStyle style = wb.createCellStyle();        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

因为传入的数据集合肯定是相同对象,所以获取第一个对象的类对象,并创建好excel文件,与第一页,页的名字就用表名来命名,并指定单元格居中显示。

第二部分:

//获取字段对象        Field[] fields = clazz.getDeclaredFields();        //字段名数组,只需要标识了注解的字段        List
names = new ArrayList
(); for(int i=0,len=fields.length;i

因为一个JavaBean有很多的属性,大部分情况下不会对全部的字段都需要导出,如何只导出指定对象的字段与值呢?作者在这里采用了注解来标识,利用Java反射获取对象的全部字段,但是却只对标识了注解的字段进行excel导出,还可以自己确定列名 

注解代码:

/** * Created by oldfish on 2017-10-20. * 导出注解类,用于标识字段是否需要导出 */@Target({ElementType.FIELD})//只作用在字段上@Retention(RetentionPolicy.RUNTIME)//运行时有效public @interface ExcelField {    //导出字段在excel的名字    String title();}

注解使用代码:

@ExcelField(title = "编号")    private Integer id; // 编号    @ExcelField(title = "用户IP")    private String userIp; // 用户IP    @ExcelField(title = "评论内容")    private String content; // 评论内容    private Blog blog; // 被评论的博客    @ExcelField(title = "评论日期")    private Date commentDate; // 评论日期    private Integer blogId;    @ExcelField(title = "审核状态")    private Integer state; // 审核状态  0 待审核 1 审核通过 2 审核未通过    private String commentDateStart; //开始日期 用于条件查询    private String commentDateEnd;//结束日期 用于条件查询

获取了需要的字段名,并用数组存储好,就需要创建好第一行用来显示字段名,循环数组长度,确定有多少列,指定好列名(就是字段名),宽度与样式等,这里有个小问题,如果指定了列名的宽度就不要宽度自适应,两者只会产生一个效果 

这里写图片描述

第三部分:

for(int j=0,l=list.size();j

然后就需要循环数据集合开始导出数据了,这里有个需要注意的地方就是第一行已经被列名占用了,所以创建行肯定是从第二行开始,同样需要判断字段有没有注解,然后反射获取值。因为单元格设置值的方法不能是Object,很蛋疼,所以需要判断类型,然后转换再赋值,如果有更好的办法,欢迎指点作者与广大读者。

还有一个坑的地方就是循环字段时,会发生某个字段不需要导出,然后顺序就会发生断层,创建单元格的时候肯定就不能用这个循环变量来创建,需要另外的循环变量,代码中已指出,如果有更简单,更效率的办法,我是很欢迎大家来指点的啦

第四部分:

response.setContentType("application/vnd.ms-excel;charset=utf-8");        //文件名使用uuid,避免重复        response.setHeader("Content-Disposition", "attachment;filename="                + UUID.randomUUID() + ".xls");        OutputStream ouputStream = null;        try {            ouputStream = response.getOutputStream();            wb.write(ouputStream);            ouputStream.flush();            ouputStream.close();        } catch (IOException e) {            throw new RuntimeException("IO异常");        }

最后用response对象设置Http协议并指定编码,用uuid指定文件名,防止重复,用输出流输出到客户端。一个基本的excel导出通用工具类就完成了….

你可能感兴趣的文章
向量的索引文件格式
查看>>
DocValues 对于一些存储的值
查看>>
Lucene的几种评分方式
查看>>
static为什么可以修饰类
查看>>
Sql Server 锁机制
查看>>
Lucene检索的一系列流程
查看>>
Lucene的索引过程,非常简洁,
查看>>
4大数据库的比较
查看>>
Java 8的特性
查看>>
Spring整合JMS----基于ActiveMQ的实现
查看>>
sql语句常用
查看>>
数据的表前缀
查看>>
ActiveMQ入门
查看>>
hibernate的延时加载的get和load的区别
查看>>
springmvc避免IE执行AJAX时,返回JSON出现下载文件
查看>>
@Resource和@Autowire的区别
查看>>
java的非对称加密算法
查看>>
spring方法拦截器 MethodInterceptor
查看>>
Greenplum八点劣势是真的吗
查看>>
hbase与传统数据的区别
查看>>