当前位置: 首页 > news >正文

sql2java-excel(一):基于apache poi实现数据库表的导出及支持spring web

sql2java是我几年年开始写的一个sql2java是一个轻量级数据库(SQL)访问代码(java)生成器。这几年一直在根据工作需要维护升级,最近的项目中需要对数据库的记录提供导出excel的功能。
就开始学习apache的POI,参照网上的示例实现了单张表的导出。并进一步将它封装成一个通用库成为sql2java下的子项目sql2java-excel.以方便在其他项目中技术复用。
本文开始介绍sql2java-excel的使用.

引入依赖

maven下引入sql2java-excel项目依赖

		<dependency>
			<groupId>com.gitee.com</groupId>
			<artifactId>sql2java-excel</artifactId>
			<version>3.10.0</version>
		</dependency>

excelGenerator

特性

基于apach/poi实现数据记录导出为excel,为Spring Web服务提供切面(aspect)支持,简化excel数据导出实现.

  • 数据记录列表支持数组,java.util.Set,java.util.List,以及以及所有实现java.lang.Iterable接口的可迭代容器类型
  • 数据记录列表元素类型支持java.util.Map,JavaBean(gu.sql2java.BeseBean,fastjson的JSONObject属于Map)
  • 支持导出为文件,及导出到javal.io.OutputStream
  • 支持导出到HTTP请求javax.servlet.http.HttpServletResponse
  • 支持(aspect)切面导出,基于Spring AOP 技术简化服务端导出Excel实现
  • 支持成员子成员导出.如 props.name.first代表成员props的子成员name的子成员first,成员及子成员字段都支持Map,Java Bean
  • 支持字段名驼峰命名(camel-case)格式与蛇形命名(snake-case)格式的自动转换,当以create_time读取字段而只存在createTime字段时会自动返回createTime字段值
  • 支持注解方式配置导出列输出顺序,导出列过滤(白名单/黑名单/隐藏名单)
  • 支持注解方式配置导出表的默认单元格格式配置:字体,颜色,填充色,对齐方式
  • 支持注解方式配置导出表的标题单元格配置:标题名,字体,颜色,填充色,对齐方式
  • 支持注解方式配置导出表的首行单元格配置:字体,颜色,填充色,对齐方式
  • 支持注解方式配置导出列的配置:输出顺序,字段名,单元格宽度,颜色,填充色,对齐方式,数据格式(DataFormat),数据转换
  • 支持简单数据类型转换表达式,参见注解类 ExcelColumnreadConverterExp()方法
  • 支持列数据自定义类型转接口,参见ExcelHandlerAdapter
  • 不支持图像数据导出

JDK requirement

JDK 要求 1.8

快速入门

定义一个Java Bean

	@Data
	public static class TestUserBean {
		private int id;
		private String name;
		private Date birthday;
		private String phone;
		private String idnum;
		public TestUserBean(int id, String name, Date birthday, String phone, String idnum) {
			super();
			this.id = id;
			this.name = name;
			this.birthday = birthday;
			this.phone = phone;
			this.idnum = idnum;
		}
	}

Excel导出调用示例

public class ExcelExportTest {

	/**
	 * 普通JavaBean记录导出到excel文件测试
	 */
	@Test  
	public void test1JavaBeanExport() {
		try(FileOutputStream outputStream = new FileOutputStream(new File("export.xlsx"))) {
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
            /** 待输出的数据记录 */
			List<TestUserBean> beans = Lists.newArrayList(
					new TestUserBean(1, "tom", fmt.parse("1976-01-01"), "13327963101", "157713197601012534"),
					new TestUserBean(15, "smith", fmt.parse("1950-03-25"), "13707968801", "201513195003257774"),
					new TestUserBean(29, "brown", fmt.parse("2003-05-13"), "13327385801", "102813200305137118"),
					new TestUserBean(3, "张小泉", fmt.parse("1999-11-28"), "13327968801", "450113199911285320"),
					new TestUserBean(7, "阿明", fmt.parse("1980-10-01"), "13366668487", "310113198010047890")
					);
            /** 创建 ExcelGenerator 实例 */
			ExcelGenerator<TestUserBean> generator = new ExcelGenerator<TestUserBean>(beans){};
            /** Excel Sheet 配置 */
			SheetConfig sheetConfig = generator.getSheetConfig();
            /** Excel Sheet 标题 */
			sheetConfig.setTitle("人员花名册");
            /** 标题居单元格填充色 */
			sheetConfig.setTitleFillColor(IndexedColors.LIGHT_YELLOW);
            /** 标题居中对齐 */
			sheetConfig.setTitleHorizontalAlign(HorizontalAlignment.CENTER);
            /** 输出到文件流 */
			generator.generate(outputStream);
		} catch (IOException | ParseException e) {
			fail(e.getMessage());
		};		
	}
}

输出的Excel
在这里插入图片描述

使用@ExcelSheet,@ExcelColumn注解

上面的输出Excel输出的列名是JavaBean中的英文字段名,而且导出字段的顺序不符合我们的要求,我们可以通过为每个字段定义@ExcelColumn注解来指定导出的列表名,用@ExcelSheet来配置Exce导出全全局配置,重新定义TestUserBean如下:

	@Data
	@ExcelSheet(title="人员花名册",titleFillColor="LIGHT_YELLOW",titleHorizontalAlign="CENTER")
	public static class TestUserBean {
		@ExcelColumn(name="用户ID",sort=1)
		private int id;
		@ExcelColumn(name="用户名",sort=2)
		private String name;
		@ExcelColumn(name="出生日期",sort=3,dateFormat="yyyy-MM-dd")
		private Date birthday;
		@ExcelColumn(name="联系电话",sort=4,integralFormat="0")
		private String phone;
		@ExcelColumn(name="身份证号码",sort=5,integralFormat="0")
		private String idnum;
		public TestUserBean(int id, String name, Date birthday, String phone, String idnum) {
			super();
			this.id = id;
			this.name = name;
			this.birthday = birthday;
			this.phone = phone;
			this.idnum = idnum;
		}
	}

则Excel导出调用代码可以简化如下示例

public class ExcelExportTest {

	/**
	 * 普通JavaBean (带{@link ExcelSheet},{@link ExcelColumn} 注解)记录导出excel测试
	 */
	@Test  
	public void test1JavaBeanExport() {
		try(FileOutputStream outputStream = new FileOutputStream(new File("export.xlsx"))) {
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
            /** 待输出的数据记录 */
			List<TestUserBean> beans = Lists.newArrayList(
					new TestUserBean(1, "tom", fmt.parse("1976-01-01"), "13327963101", "157713197601012534"),
					new TestUserBean(15, "smith", fmt.parse("1950-03-25"), "13707968801", "201513195003257774"),
					new TestUserBean(29, "brown", fmt.parse("2003-05-13"), "13327385801", "102813200305137118"),
					new TestUserBean(3, "张小泉", fmt.parse("1999-11-28"), "13327968801", "450113199911285320"),
					new TestUserBean(7, "阿明", fmt.parse("1980-10-01"), "13366668487", "310113198010047890")
					);
            /** 创建 ExcelGenerator 实例 */
			ExcelGenerator<TestUserBean> generator = new ExcelGenerator<TestUserBean>(beans){};
			generator.generate(outputStream);
		} catch (IOException | ParseException e) {
			fail(e.getMessage());
		};		
	}
}

导出的Excel
在这里插入图片描述

Map记录导出示例

ExcelGenerator支持导出数据记录的元素类型为Map.示例如下:

	/**
	 * Map记录导出excel测试
	 */
	@SuppressWarnings("rawtypes")
	@Test  
	public void test3MapExport() {
		try(FileOutputStream outputStream = new FileOutputStream(new File("export.xlsx"))) {
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
			/** 待输出的数据记录 */
			ArrayList<Map> beans = Lists.newArrayList(
					ImmutableMap.of("id", 1, "name", "tom", "birthday", fmt.parse("1976-01-01"), "phone", "13327963101", "idnum", "157713197601012534"),
					ImmutableMap.of("id", 15, "name", "smith", "birthday", fmt.parse("1950-03-25"), "phone", "13707968801", "idnum", "201513195003257774"),
					ImmutableMap.of("id", 29, "name", "brown", "birthday", fmt.parse("2003-05-13"), "phone", "13327385801", "idnum", "102813200305137118"),
					ImmutableMap.of("id", 3, "name", "张小泉", "birthday", fmt.parse("1999-11-28"), "phone", "13327968801", "idnum", "450113199911285320"),
					ImmutableMap.of("id", 7, "name", "阿明", "birthday", fmt.parse("1980-10-01"), "phone", "13366668487", "idnum", "310113198010047890")
					);
			
			/** 创建 ExcelGenerator 实例 */
			ExcelGenerator<Map> generator = new ExcelGenerator<Map>(beans){};
            /** 也可以使用为Map类型定义的便利化封装类MapExcelGenerator */
            //MapExcelGenerator generator = new MapExcelGenerator(beans);
			/** Excel Sheet 配置 */
			SheetConfig sheetConfig = generator.getSheetConfig();
			/** Excel Sheet 标题 */
			sheetConfig.setTitle("人员花名册");
			/** 标题居单元格填充色 */
			sheetConfig.setTitleFillColor(IndexedColors.LIGHT_YELLOW);
			/** 标题居中对齐 */
			sheetConfig.setTitleHorizontalAlign(HorizontalAlignment.CENTER);
            /** 定义导出字段名及数据格式 */
			sheetConfig.configOf("id").getColumnConfig().setName("用户ID");
			sheetConfig.configOf("name").getColumnConfig().setName("用户名");
			sheetConfig.configOf("birthday").getColumnConfig().setName("出生日期").setDateFormat("yyyy-MM-dd");
			sheetConfig.configOf("phone").getColumnConfig().setName("联系电话");
			sheetConfig.configOf("idnum").getColumnConfig().setName("身份证号码");
			/** 输出到文件流 */
			generator.generate(outputStream);
		} catch (IOException | ParseException e) {
			fail(e.getMessage());
		};		
	}

导出的Excel
在这里插入图片描述

子成员导出

ExcelGenerator支持子成员导出,子成员的引用名格式为自顶向下以.分割的各级成员名

如下我们在TestUserBean中增加一个类型为com.alibaba.fastjson.JSONObject()的props字段用于保存用户的扩展信息,

@ExcelSheet注解中增加includeColumns配置导出的字段,其中props.salaryprops.carprops字段的子成员,同时定义将props定义为隐藏字段(hideColumns)

	@Data
	@ExcelSheet(title="人员花名册",titleFillColor="LIGHT_YELLOW",
						titleHorizontalAlign="CENTER",
						hideColumns="props",
						includeColumns={"id","name","birthday","phone","idnum","props.salary","props.car"})
	public static class TestUserBean {
		@ExcelColumn(name="用户ID",sort=1)
		private int id;
		@ExcelColumn(name="用户名",sort=2)
		private String name;
		@ExcelColumn(name="出生日期",sort=3,dateFormat="yyyy-MM-dd")
		private Date birthday;
		@ExcelColumn(name="联系电话",sort=4,integralFormat="0")
		private String phone;
		@ExcelColumn(name="身份证号码",sort=5,integralFormat="0")
		private String idnum;
		private JSONObject props;
		public TestUserBean(int id, String name, Date birthday, String phone, String idnum) {
			super();
			this.id = id;
			this.name = name;
			this.birthday = birthday;
			this.phone = phone;
			this.idnum = idnum;
		}
		public TestUserBean(int id, String name, Date birthday, String phone, String idnum, JSONObject props) {
			super();
			this.id = id;
			this.name = name;
			this.birthday = birthday;
			this.phone = phone;
			this.idnum = idnum;
			this.props = props;
		}
	}

修改test2JavaBeanExport测试代码如下,在测试数据中为每个用户定义props字段

	/**
	 * 普通JavaBean (带{@link ExcelSheet},{@link ExcelColumn} 注解)记录导出excel测试
	 */
	@Test  
	public void test2JavaBeanExport() {
		try(FileOutputStream outputStream = new FileOutputStream(new File("export.xlsx"))) {
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
			/** 待输出的数据记录 */
			List<TestUserBean> beans = Lists.newArrayList(
					new TestUserBean(1, "tom", fmt.parse("1976-01-01"), "13327963101", "157713197601012534",new JSONObject().fluentPut("salary", 5000).fluentPut("car", "京AA4382")),
					new TestUserBean(15, "smith", fmt.parse("1950-03-25"), "13707968801", "201513195003257774",new JSONObject().fluentPut("salary", 60000)),
					new TestUserBean(29, "brown", fmt.parse("2003-05-13"), "13327385801", "102813200305137118",new JSONObject().fluentPut("salary", 3200)),
					new TestUserBean(3, "张小泉", fmt.parse("1999-11-28"), "13327968801", "450113199911285320",new JSONObject().fluentPut("salary", 200)),
					new TestUserBean(7, "阿明", fmt.parse("1980-10-01"), "13366668487", "310113198010047890",new JSONObject().fluentPut("salary", 350000).fluentPut("car", "粤AS9988"))
					);
			/** 创建 ExcelGenerator 实例 */
			ExcelGenerator<TestUserBean> generator = new ExcelGenerator<TestUserBean>(beans){};
			/** Excel Sheet 配置 */
			SheetConfig sheetConfig = generator.getSheetConfig();
            /** 定义扩展字段的列名 */
			sheetConfig.configOf("props.salary").getColumnConfig().setName("工资");
			sheetConfig.configOf("props.car").getColumnConfig().setName("车牌");
			generator.generate(outputStream);
		} catch (IOException | ParseException e) {
			fail(e.getMessage());
		};		
	}

输出的Excel
在这里插入图片描述
完整示例代码参见:
https://gitee.com/l0km/sql2java/blob/master/sql2java-excel/src/test/java/gu/sql2java/excel/ExcelExportTest.java

关于Spring支持参见下一篇博客:
《sql2java-excel(二):基于apache poi实现数据库表的导出的spring web支持》

相关文章:

  • SSM保险办理系统毕业设计源码012232
  • 先睹为快_Mandelbrot集
  • centos 7 安装mysql 8.0.30
  • TR5521设计资料|TR5521替代方案|DP转VGA设计参考
  • javaweb教师招聘管理系统ssm
  • spring boot —— Spring Security定制权限管理
  • Python从入门到实践:包的使用
  • kubernetes二进制安装教程单master
  • LeetCode-998. 最大二叉树 II【最大二叉树】
  • 如何快速使用proteus【硬件课程设计】
  • 从零开始手写一个Transformer
  • java基于springboot+Vue图片分享社区网站
  • Appium环境搭建及元素定位
  • 神经网络算法处理器设计,神经网络是机器算法吗
  • 爱上开源之golang入门至实战第四章函数(Func)(九)
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 【前端学习】-粗谈选择器
  • 4. 路由到控制器 - Laravel从零开始教程
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Webpack 4 学习01(基础配置)
  • win10下安装mysql5.7
  • 阿里云应用高可用服务公测发布
  • 普通函数和构造函数的区别
  • 悄悄地说一个bug
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 删除表内多余的重复数据
  • 设计模式走一遍---观察者模式
  • 深度学习中的信息论知识详解
  • 微信小程序--------语音识别(前端自己也能玩)
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #数学建模# 线性规划问题的Matlab求解
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (42)STM32——LCD显示屏实验笔记
  • (pojstep1.3.1)1017(构造法模拟)
  • (二)PySpark3:SparkSQL编程
  • (附源码)计算机毕业设计高校学生选课系统
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (数据结构)顺序表的定义
  • (算法)N皇后问题
  • (一)Dubbo快速入门、介绍、使用
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .Net IOC框架入门之一 Unity
  • .NET Micro Framework 4.2 beta 源码探析
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .NET框架
  • .NET微信公众号开发-2.0创建自定义菜单