excel导出工具
介绍
excel导出工具
整个项目的代码结构如下
com \---utils +---demo # 案例相关 | | ExcelExportApplication.java # springboot启动类 | | | +---bean | | DemoBean.java # 测试bean | | | +---controller | | ExcelExportController.java # 测试url访问弹出下载excel文件和导出excel到文件 | | | \---exportParam | | DemoExportParam.java # 导出参数 | | | \---dataConversion | HobbyConversion.java # 爱好属性导出转换类 | SexConversion.java # 性别属性导出转换类 | \---excelExport # 导出工具包 | AsyncExportExcel.java #多线程导出 | ExportExcel.java # 导出工具类 | +---data | BaseParam.java # 基础导出参数类 | +---dataConversion | DataExportConversion.java # 属性导出转换接口 | +---defaultDataHandle # 默认的数据处理 | AbstractDataHandler.java | BooleanDataHandler.java | DataHandlerFactory.java | DateDataHandler.java | StringDataHandler.java | \---style # 默认的样式 AbstractCellStyle.java DefaultDataCellStyle.java DefaultTitleCellStyle.java
简单的来说excel导出可以分为几步
- 获得需要导出的数据
- 设置excel的工作表(sheet)名称
- 设置当前工作表的第一行,也就是标题行
- 将数据逐行填充,有需要的数据进行转换
使用
ExportExcel工具类
首先实例化ExportExcel工具类,我这里提供了三个构造函数
public ExportExcel() public ExportExcel(SXSSFWorkbook workbook) public ExportExcel(SXSSFWorkbook workbook, AbstractCellStyle titleCellStyle, AbstractCellStyle dataCellStyle)
通常使用的是无参构造函数。另外两个都需要自己实例化workbook对象,有三个参数的构造函数,需要传入workbook、标题行样式对象、数据行样式对象。关于样式对象下方有说明。
实例化ExportExcel工具类之后,需要调用exportExcel方法,方法定义如下
public void exportExcel(String sheetName, BaseParam baseParam, OutputStream out)
参数名称 | 参数内容 |
---|---|
sheetName | 工作表(sheet)的名称 |
baseParam | 继承BaseParam的导出参数对象(后面会说明) |
out | OutputStream对象、例如FileOutputStream |
样式抽象类AbstractCellStyle
public abstract class AbstractCellStyle { Workbook workbook; CellStyle style; Font font; public AbstractCellStyle(Workbook workbook) { this.workbook = workbook; style = workbook.createCellStyle(); font = workbook.createFont(); } protected abstract void setStyle(); protected abstract void setFont(); public CellStyle getCellStyle() { style.setFont(font); return style; } }
通过继承样式抽象类AbstractCellStyle,可以实现下方两个方法
// 设置样式 protected abstract void setStyle(); // 设置字体 protected abstract void setFont();
通过这两个方法可以修改单元格的样式和字体。
基础导出参数类BaseParam
BaseParam类代码如下
public class BaseParam { public List data = new ArrayList<>(); public List<ColumnParam> columnParams = new ArrayList<>(); //Set Get Constructor /** * 数据行参数 */ public class ColumnParam{```} }
属性
可以看到BaseParam类有两个属性
public List data = new ArrayList<>(); public List<ColumnParam> columnParams = new ArrayList<>();
data毫无疑问是存放需要导出的数据,而columnParams是存放每一列的数据,现在来看看内部类ColumnParam
内部类ColumnParam
public class ColumnParam{ private String headerName; private String fieldName; private DataExportConversion conversion;//数据转换 //Set Get Constructor }
属性
属性名称 | 属性内容 |
---|---|
headerName | 标题名称 |
fieldName | 实体类对应的属性名 |
conversion | 数据转换对象 |
数据转换接口DataExportConversion
public interface DataExportConversion<T> { String transferData(T data); }
比如说,获取出来的数据是0、1,然后你需要将数据转换成女、男,那么就可以实现数据转换接口DataExportConversion,自定义转换输出的格式,代码如下
public class SexConversion implements DataExportConversion<Integer> { @Override public String transferData(Integer data) { if (0 == data){ return "女"; } else if (1 == data){ return "男"; } return "不详"; } }
案例
场景
原始数据如下
姓名 | 性别 | 出生日期 | 爱好(List对象) |
---|---|---|---|
尘心 | 0 | 2018-08-08 14:59:11 | [舞刀,弄枪] |
千月 | 1 | 2018-08-08 14:59:11 | [唱歌,跳舞] |
需要转换为下方内容
姓名 | 性别 | 出生日期 | 爱好 |
---|---|---|---|
尘心 | 女 | 2018-08-08 14:59:11 | 舞刀,弄枪 |
千月 | 男 | 2018-08-08 14:59:11 | 唱歌,跳舞 |
实体类如下
public class DemoBean { //姓名 private String name; //性别,0->女,1->男 private Integer sex; //出生日期 private Date birthday; //爱好 private List<String> hobbies; //Set Get }
数据转换
可以看到有两个属性需要转换,分别是性别和爱好。性别的数据转换上面已经有了,就不贴出来了,下面是爱好的数据转换
public class HobbyConversion implements DataExportConversion<List<String>> { @Override public String transferData(List<String> data) { StringBuilder hobby = new StringBuilder(); for (String s:data){ hobby.append(s).append(","); } //移除最后一个逗号 if (hobby.length() >= 1){ hobby.deleteCharAt(hobby.length()-1); } return hobby.toString(); } }
导出参数类
数据转换类写好了之后,开始编写导出参数类,代码如下
public class DemoExportParam extends BaseParam { public DemoExportParam(List<DemoBean> list) { setData(list); setColumnParam(); } private void setColumnParam() { columnParams.add(new ColumnParam("姓名","name")); columnParams.add(new ColumnParam("性别","sex", new SexConversion())); columnParams.add(new ColumnParam("出生日期","birthday")); columnParams.add(new ColumnParam("爱好","hobbies", new HobbyConversion())); } }
在实例化DemoExportParam时,需要传入导出的数据,同时设置每一列对应的列参数ColumnParam。
可以看到总共有4个列参数
- 第一列标题名称为姓名,对应的属性名称为name
- 第二列标题名称为性别,对应的属性名称为sex,还有数据转换对象SexConversion
- 第三列标题名称为出生日期,对应的属性名称为birthday
- 第四列标题名称为爱好,对应的属性名称为hobbies,数据转换对象HobbyConversion
导出
先写一个生成数据的方法,如下
private List<DemoBean> getDemoBeanList(){ DemoBean man = new DemoBean(); DemoBean woman = new DemoBean(); String[] manHobbys = {"舞刀", "弄枪"}; String[] womanHobbys = {"唱歌", "跳舞"}; man.setName("尘心").setBirthday(new Date()).setSex(0).setHobbies(Arrays.asList(manHobbys)); woman.setName("千月").setBirthday(new Date()).setSex(1).setHobbies(Arrays.asList(womanHobbys)); //将两个bean添加到list中 List<DemoBean> list = new ArrayList<>(); list.add(man); list.add(woman); return list; }
接下来有两种数据导出方式,一种是url访问弹出下载excel文件,另外一种是导出excel到文件
url访问弹出下载excel文件
@ResponseBody @RequestMapping("/export") public void exportByWeb(HttpServletResponse response) throws IOException { OutputStream out = new BufferedOutputStream(response.getOutputStream()); response.reset(); String headStr = "attachment; filename=" + URLEncoder.encode("导出demo.xlsx", "utf-8"); response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Content-Disposition", headStr); //获得导出数据 List<DemoBean> list = getDemoBeanList(); DemoExportParam demoExportParam = new DemoExportParam(list); ExportExcel exportExcel = new ExportExcel(); exportExcel.exportExcel("demo", demoExportParam, response.getOutputStream()); out.flush(); out.close(); }
导出excel到文件
@Test public void exportByFile() throws IOException { File file = new File("F:\\导出demo.xlsx"); FileOutputStream out = new FileOutputStream(file); //获得导出数据 List<DemoBean> list = getDemoBeanList(); DemoExportParam demoExportParam = new DemoExportParam(list); ExportExcel exportExcel = new ExportExcel(); exportExcel.exportExcel("demo", demoExportParam, out); out.flush(); out.close(); }
项目位置:https://github.com/rainbowda/utils/tree/master/excel_export,有需要的可以去下载。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
使用PHP搭建Web版Docker管理系统实践
版权声明:作者:汤青松 https://blog.csdn.net/u013431141/article/details/81612523 一、背景 团队中使用容器比较频繁,但并不是所有人都可以登陆服务器去执行命令,但是又需要用到docker,所以有一个需求通过web来管理docker,而其他语言并不怎么熟悉,后期维护成本比较高,所以笔者采用PHP来管理容器。 在技术调研阶段,笔者一开始想的是用php的system来执行docker命令,后来查找了相关资料发现,原来docker本身提供了一套API来管理它,因此倒省了很多事情。 二、操作概要 开启Docker Remote Api 搭建Web-docker 功能验证与测试 三、开启Docker Remote Api docker提供API支持,但是默认情况下并没有开启,因此需要使用的时候需要把API功能开启,笔者开启的方法选择了socat这个组件,下面介绍一下如何安装及启动socat,这里介绍brew和docker分别的安装方法,读者只需要采用其中一种即可。 参考文档:Docker on Mac上的Remote API 远程控制 3.1...
- 下一篇
Java Optional空指针处理
那些年困扰着我们的null 在Java江湖流传着这样一个传说:直到真正了解了空指针异常,才能算一名合格的Java开发人员。在我们逼格闪闪的java码字符生涯中,每天都会遇到各种null的处理,像下面这样的代码可能我们每天都在反复编写: if(null != obj1){ if(null != obje2){ // do something } } 稍微有点眼界javaer就去干一些稍有逼格的事,弄一个判断null的方法: boolean checkNotNull(Object obj){ return null == obj ? false : true; } void do(){ if(checkNotNull(obj1)){ if(checkNotNull(obj2)){ //do something } } } 然后,问题又来了:如果一个null表示一个空字符串,那""表示什么? 然后惯性思维告诉我们,""和null不都是空字符串码?索性就把判断空值升级了一下: boolean checkNotBlank(Object obj){ return null != obj &...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- 2048小游戏-低调大师作品
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G