java实现Excel导出(springboot)
文章目录
- 一、完成相关配置
- 1.导入依赖
- 2.定义Excel注解以及Excels注解
- 3、给实体类添加Excel注解
- 二、Excel方法类
- 1.大致路线
- 2.定义ExcelUtil中的变量
- 3.ExcelUtil中的Excel导出方法
- 3.1 exportExcel(List list, String sheetName)
- init(List list, String sheetName, Type type)
- 3.2 exportExcel()
- 3.2.1.createSheet()创建工作表
- 3.2.2createCell()创建单元格
- 3.2.3 fillExcelData()填充excel数据
- 3.2.4.addStatisticsRow()创建统计行
- 4.ExcelUtil中的返回给前端文件名部分
- 三、controller
一、完成相关配置
1.导入依赖
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId>
</dependency>
2.定义Excel注解以及Excels注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{/*** 导出时在excel中排序*/public int sort() default Integer.MAX_VALUE;/*** 导出到Excel中的名字.*/public String name() default "";/*** 日期格式, 如: yyyy-MM-dd*/public String dateFormat() default "";/*** 如果是字典类型,请设置字典的type值 (如: sys_user_sex)*/public String dictType() default "";/*** 读取内容转表达式 (如: 0=男,1=女,2=未知)*/public String readConverterExp() default "";/*** 分隔符,读取字符串组内容*/public String separator() default ",";/*** BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)*/public int scale() default -1;/*** BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN*/public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;/*** 导出类型(0数字 1字符串)*/public ColumnType cellType() default ColumnType.STRING;/*** 导出时在excel中每个列的高度 单位为字符*/public double height() default 14;/*** 导出时在excel中每个列的宽 单位为字符*/public double width() default 16;/*** 文字后缀,如% 90 变成90%*/public String suffix() default "";/*** 当值为空时,字段的默认值*/public String defaultValue() default "";/*** 提示信息*/public String prompt() default "";/*** 设置只能选择不能输入的列内容.*/public String[] combo() default {};/*** 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.*/public boolean isExport() default true;/*** 另一个类中的属性名称,支持多级获取,以小数点隔开*/public String targetAttr() default "";/*** 是否自动统计数据,在最后追加一行统计数据总和*/public boolean isStatistics() default false;/*** 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右)*/Align align() default Align.AUTO;public enum Align{AUTO(0), LEFT(1), CENTER(2), RIGHT(3);private final int value;Align(int value){this.value = value;}public int value(){return this.value;}}/*** 字段类型(0:导出导入;1:仅导出;2:仅导入)*/Type type() default Type.ALL;public enum Type{ALL(0), EXPORT(1), IMPORT(2);private final int value;Type(int value){this.value = value;}public int value(){return this.value;}}public enum ColumnType{NUMERIC(0), STRING(1);private final int value;ColumnType(int value){this.value = value;}public int value(){return this.value;}}
}
/*** Excel注解集* */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels {Excel[] value();
}
3、给实体类添加Excel注解
@Data
@TableName("t_enterprise")
public class Enterprise {@TableField(exist = false)private List<Category> category;@TableField(exist = false)private Region region;@TableField(exist = false)private User user;@TableField(exist = false)private List<Integer>categoryId;//企业分类id@TableField(exist = false)private String operateStatus;@TableId(type = IdType.AUTO)@Excel(name = "序号", cellType = Excel.ColumnType.NUMERIC)private Integer id;@Excel(name = "企业名称")private String name;@Excel(name = "所属区域")private Integer regionId;@Excel(name = "详细地址")private String address;@Excel(name = "注册资本")private Long registerCapital;@Excel(name = "成立日期",width = 30, dateFormat = "yyyy-MM-dd")private LocalDateTime establishDate;@Excel(name = "经营范围")private String businessScope;@Excel(name = "联系方式")private String phone;@Excel(name = "企业LOGO")private String logoUrl;@Excel(name = "企业用户ID")private Integer enterpriseUserId;@Excel(name = "视频推送状态#0:正常#1:优推#2:下架")private Integer pushStatus;@Excel(name = "优势产品")private String featureProduct;@Excel(name = "优势分析")private String advantageAnalysis;@Excel(name = "隐私设置#0:显示#1:隐藏")private String privacySetting;@Excel(name = "运营状态ID")private Integer operateStatusId;@Excel(name = "统一信用社会代码")private String socialCode;@Excel(name = "营业执照" )private String licenseUrl;@Excel(name = "法人身份证")private String legalPersonCardUrl;@Excel(name = "企业认证公函")private String letterUrl;@Excel(name = "管理人")private String manager;@Excel(name = "法人")private String legalPerson;@Excel(name = "法人联系方式")private String legalPersonPhone;@Excel(name = "审核状态#0:未审核#1:通过#2:驳回")private Integer auditStatus;@Excel(name = "驳回原因")private String rejectionReason;@Excel(name = "审核时间",width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")private LocalDateTime auditTime;@ApiModelProperty(value = "更新时间")@TableField(fill = FieldFill.INSERT_UPDATE)@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")private LocalDateTime updateTime;@ApiModelProperty(value = "创建时间")@TableField(fill = FieldFill.INSERT)@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;@TableField(exist=false)@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")private LocalDateTime createTimeBegin;@TableField(exist=false)@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")private LocalDateTime createTimeEnd;@Excel(name = "删除标识")private Boolean deleteFlag;@Excel(name = "视频")private String videoUrl;@Excel(name="隐私设置")@TableField(exist = false)private String privacy;
二、Excel方法类
1.大致路线
2.定义ExcelUtil中的变量
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);/*** Excel sheet最大行数,默认65536*/public static final int sheetSize = 65536;/*** 工作表名称*/private String sheetName;/*** 导出类型(EXPORT:导出数据;IMPORT:导入模板)*/private Type type;/*** 工作薄对象*/private Workbook wb;/*** 工作表对象*/private Sheet sheet;/*** 样式列表*/private Map<String, CellStyle> styles;/*** 导入导出数据列表*/private List<T> list;/*** 注解列表*/private List<Object[]> fields;/*** 统计列表*/private Map<Integer, Double> statistics = new HashMap<Integer, Double>();/*** 数字格式*/private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");/*** 实体对象*/public Class<T> clazz;public ExcelUtil(Class<T> clazz) {this.clazz = clazz;}
public ExcelUtil(Class<T> clazz) {this.clazz = clazz;//构造方法的参数是要导出的实体类class,赋值给clazz变量}
3.ExcelUtil中的Excel导出方法
3.1 exportExcel(List list, String sheetName)
/*** 对list数据源将其里面的数据导入到excel表单** @param list 导出数据集合* @param sheetName 工作表的名称* @return 结果*/public ResultJson exportExcel(List<T> list, String sheetName) {this.init(list, sheetName, Type.EXPORT);return exportExcel();}
init(List list, String sheetName, Type type)
将需要的导出的数据和文件名,及区分导出还是导入的Type赋值给变量。
这里type为EXPORT(导出)。
public void init(List<T> list, String sheetName, Type type) {if (list == null) {list = new ArrayList<T>();}this.list = list;this.sheetName = sheetName;this.type = type;createExcelField();createWorkbook();}
init中的createExcelField
/*** 得到所有定义字段*/private void createExcelField() {this.fields = new ArrayList<Object[]>();List<Field> tempFields = new ArrayList<>();tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));for (Field field : tempFields) {// 单注解if (field.isAnnotationPresent(Excel.class)) {//isAnnotationPresent() 判断该字段是否标注该注解putToField(field, field.getAnnotation(Excel.class));}// 多注解if (field.isAnnotationPresent(Excels.class)) {Excels attrs = field.getAnnotation(Excels.class);Excel[] excels = attrs.value();for (Excel excel : excels) {putToField(field, excel);}}}this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());}
fields用来存储所有Excel注解的字段,为Object[]
clazz.getSuperclass()为得到实体类的父类方法。
getDeclaredFields()为反射中的方法,获得某个类的所有声明的字段,即包括public,private 和proteced,但是不包括父类的申明字段,所以先获取了父类的声明字段,再获取当前类的声明字段。
Array.asList()是将数组转化成List集合的方法,用此方法得到的List的长度是不可改变的
createExcelField中的putToField:
将实体类中带有Excel注解的字段(field)以及注解的参数(attr)放在了fileds<Object[]>中
/*** 放到字段集合中*/private void putToField(Field field, Excel attr) {if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) {this.fields.add(new Object[]{field, attr});}}
init中的createWorkbook
/*** 创建一个工作簿*/public void createWorkbook() {this.wb = new SXSSFWorkbook(500);}
3.2 exportExcel()
对list数据源将其里面的数据导入到excel表单
执行流程为:1.createSheet() 2.createStyles() 3.createCell() 4.fillExcelData() 5.addCell()
exportExcel方法中将数据源填入excel部分:
OutputStream out = null;try {// 取出一共有多少个sheet.double sheetNo = Math.ceil(list.size() / sheetSize);for (int index = 0; index <= sheetNo; index++) {createSheet(sheetNo, index);// 产生一行Row row = sheet.createRow(0);int column = 0;// 写入各个字段的列头名称for (Object[] os : fields) {Excel excel = (Excel) os[1];this.createCell(excel, row, column++);}if (Type.EXPORT.equals(type)) {fillExcelData(index, row);addStatisticsRow();}}
3.2.1.createSheet()创建工作表
/*** 创建工作表** @param sheetNo sheet数量* @param index 序号*/public void createSheet(double sheetNo, int index) {this.sheet = wb.createSheet();this.styles = createStyles(wb);// 设置工作表的名称.if (sheetNo == 0) {wb.setSheetName(index, sheetName);} else {wb.setSheetName(index, sheetName + index);}}
createStyle():
创建表格样式
/*** 创建表格样式** @param wb 工作薄对象* @return 样式列表*/private Map<String, CellStyle> createStyles(Workbook wb) {// 写入各条记录,每条记录对应excel表中的一行Map<String, CellStyle> styles = new HashMap<String, CellStyle>();CellStyle style = wb.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);style.setBorderRight(BorderStyle.THIN);style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderLeft(BorderStyle.THIN);style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderTop(BorderStyle.THIN);style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderBottom(BorderStyle.THIN);style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());Font dataFont = wb.createFont();dataFont.setFontName("Arial");dataFont.setFontHeightInPoints((short) 10);style.setFont(dataFont);styles.put("data", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setFillPattern(FillPatternType.SOLID_FOREGROUND);Font headerFont = wb.createFont();headerFont.setFontName("Arial");headerFont.setFontHeightInPoints((short) 10);headerFont.setBold(true);headerFont.setColor(IndexedColors.WHITE.getIndex());style.setFont(headerFont);styles.put("header", style);style = wb.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);Font totalFont = wb.createFont();totalFont.setFontName("Arial");totalFont.setFontHeightInPoints((short) 10);style.setFont(totalFont);styles.put("total", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(HorizontalAlignment.LEFT);styles.put("data1", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(HorizontalAlignment.CENTER);styles.put("data2", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(HorizontalAlignment.RIGHT);styles.put("data3", style);return styles;}
3.2.2createCell()创建单元格
创建完工作表,需要添加表头信息
/*** 创建单元格*/public Cell createCell(Excel attr, Row row, int column) {// 创建列Cell cell = row.createCell(column);// 写入列信息cell.setCellValue(attr.name());setDataValidation(attr, row, column);cell.setCellStyle(styles.get("header"));return cell;}
效果:
setDataValidation: 设置表头的单元格样式
java实现Excel导出(springboot)相关推荐
- java中Excel导出echart图片
java中Excel导出echart图片 1.在生成echart的前端代码生成图片代码后Echart.setOption(captestRcapEchartOption, true);后面加上以下代码 ...
- java实现excel导出合并单元格
随着数据的不断增长,很多时候需要将数据导出到Excel中进行分析.处理和展示.而Java作为一种流行的编程语言,自然也提供了很多实现Excel导出的方法.本文将介绍如何使用Java实现Excel导出, ...
- java的Excel导出方式总结
一.使用hutool导出excel 1.1 hutool介绍 hutool功能很强大,http请求到json处理.excel的导入导出.定时任务.IO.缓存.数据库操作等都提供了简单而方便的api供我 ...
- 记一次java实现excel导出
新年过完了哦,小子我又来了,大家新年过的还快乐吗?反正我是只感觉到了"快,",没有感觉到"乐". 2021年的第一天,就接到新需求了.对,就是那个谁,来来,给个 ...
- java完成excel导出下载
废话不多说,直接上代码! 一.添加依赖 <!-- excel导出相关依赖 --><dependency><groupId>org.apache.poi</gr ...
- Java之Excel导出工具类使用教程
前言: 本工具类经过PostMan和web页面严格测试可用,经过了多个版本迭代优化,可以直接使用,也方便大家根据自己的业务需求,修改定制自己的导出工具. 市面上有很多封装好的导出工具(如:阿里的eas ...
- java poi excel导出
直接上代码 0. pom依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypo ...
- Java的Excel导出方案介绍
Apache POI方案可以对数据导出成excel表格,大部分的教程也都是基于poi进行的,但是基于poi他的api比较复杂 现在流行的一个方案就是对poi进行封装,把api的细节屏蔽,直接跟实体类进 ...
- java 实现excel 导出功能
实现功能:java导出excel表 1.jsp代码 1 <form id="zhanwForm" action="<%=path%>/conferenc ...
最新文章
- 2021年中国工业互联网安全大赛核能行业赛道writeup之隐写
- Selenium Python 解决 UnexpectedAlertPresentException
- 几个名校学霸、大厂前辈的原创公众号
- 音视频技术开发周刊(第130期)
- Luogu2495[SDOI2011]消耗战
- No ExecutorFactory found to execute the application
- PyTorch框架学习二十——模型微调(Finetune)
- BBAug: 一个用于PyTorch的物体检测包围框数据增强包
- 还服务器网站被k,导致网站被K的主要原因,看看你有没有中招!
- a6gpp php,内行人才知道的古董级玛莎拉蒂A6G 2000
- 工业互联网巨头 GE Digital 修复SCADA 软件中的两个高危漏洞
- 排序算法之 插入排序
- SSM整理笔记3——配置解析
- 九度OJ题目1000: A + B(数学)
- 机器学习实验——回归预测算法
- SRS RTC NACK源码分析—1
- 「案例」让房东在 Airbnb 上展示他们的热情好客
- 数据库防火墙闪亮登场(好文共赏)
- javascript中获取非行间样式的方法
- Django Web 开发极简实战
热门文章
- 机器学习 の04 梯度提升决策树GBDT
- 如何修改xadmin的菜单设置
- 视频网站节约流量的小妙招
- bzoj 4883 [Lydsy1705月赛]棋盘上的守卫 题解(思维,建图,最小基环森林)
- 谷歌注册提示无法验证手机号如何解决,2023年方法分享
- 联想Filez携手浙江中烟,发力“云”端,打造“烟草上云”新势能
- 隐形的翅膀 vijos_1237 (离散)
- 深入理解Condition实现原理
- 编写10个线程,第一个线程从1加到10,第二个线程从11加到20…第十个线程从91加到100, 最后再把10个线程结果相加。
- bcrypt java maven_BCrypt 密码加密