2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > EasyExcel第三弹 + hutool-poi 配合使用导出较复杂Excel.xlsx + 计算增长率 同比环比 比重等

EasyExcel第三弹 + hutool-poi 配合使用导出较复杂Excel.xlsx + 计算增长率 同比环比 比重等

时间:2019-02-28 19:48:38

相关推荐

EasyExcel第三弹 + hutool-poi 配合使用导出较复杂Excel.xlsx + 计算增长率 同比环比 比重等

一、回顾

继上次“动态表头easyExcel导入导出(/qq_37337660/article/details/114680512)”,

和上上次“动态表头导入(/qq_37337660/article/details/110288393)”之后。

我们迎来了第三波【easyExcel官网】的折磨,这次导出复杂的Excel,顺便用了【hutool官网】里面的Excel功能。

1.第一步是设计模板,利用模板导出一份新的xlsx;

2.第二步是利用hutool把新的xlsx读取,然后往里加数据,同时调整格式,合并单元格,改动sheet名称等。

需求:导出:多页sheet、复杂表头、sheet名称改动、单元格合并、简单格式调整

分析:以上这个sheet0的格式要求,可以看出前面几列的格式非常复杂且固定、表头也是相对固定。我们只要把剩下的空白格子和标题利用填充的办法就可以搞定。模板如下:

二、easyExcel的填充功能

官网填充:/easyexcel/doc/fill

这次就少说废话了,代码都加上了注释

private String doFill() {String fileName = unit.getShortname() + startTime + "—" + endTime + "导出.xlsx";// 指定新文件的路径和名称File file = new File(FORM_STORE_PATH + fileName);if (!file.getParentFile().exists()) {boolean mkdirs = file.getParentFile().mkdirs();}String newFile = file.getPath();// 这里是填充的模板,放到resource下InputStream template = this.getClass().getResourceAsStream("/template/模板.xlsx");com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(newFile).withTemplate(template).build();// 开始填充(我这里有8个sheet,每一个里面都有标题动态填充。这里先把标题填充好,把sheet0、2的内容填充好)for (int sheetNo = 0; sheetNo < 8; sheetNo++) {WriteSheet writeSheet = EasyExcelFactory.writerSheet(sheetNo).build();writeSheet.setSheetName(getSheetNameBySheetNo(sheetNo));FillConfig fillConfig =FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();excelWriter.fill(new FillWrapper("CommonTitle", Collections.singleton(title)),// 这个就是模板里面的前缀fillConfig,writeSheet);switch (sheetNo) {case 0:excelWriter.fill(new FillWrapper("data", getData()),// "data"这个就是模板里面的前缀writeSheet);break;case 2:excelWriter.fill(new FillWrapper("data", getData()),// 这个就是模板里面的前缀writeSheet);break;default:break;}}excelWriter.finish();return fileName;}//这里严格按照定义的顺序封装数据。list有几行,就会往下填充几行(当然也可以用map装数据,可以看看官网怎么用的)private List<Sheet02Statistic> getData() {}//实体类定义如下public class Sheet02Statistic {/** 本期 */private Long bq;/** 上期 */private Long sq;/** 本期增长率 */private String bqRate;/** 去年同期 */private Long qntq;/** 去年同期增长率 */private String qntqRate;/** 今年以来 */private Long jnyl;/** 今年以来增长率 */private String jnylRate;}

三、hutool的Excel生成-ExcelWriter

各类用法参考官网:/docs/#/poi/Excel%E7%94%9F%E6%88%90-ExcelWriter

原始第8个sheet:

通过下面代码生成后的:

这里截取部分代码:

// newFilePath 是刚刚用模板生成的文件的路径private void doWrite(String newFilePath) {cn.hutool.poi.excel.ExcelWriter writer = ExcelUtil.getWriter(newFilePath);writeSheet1(writer);writeSheet3(writer);writeSheet5(writer);writeSheet6(writer);writeSheet7(writer);writeSheet8(writer);//这里改sheet名称writer.renameSheet(0, title.getSheet0());writer.renameSheet(1, title.getSheet1());writer.renameSheet(2, title.getSheet2());writer.renameSheet(7, title.getSheet7());//如果有用了公式,用这个来使公式生效Workbook workbook = writer.getWorkbook();workbook.setForceFormulaRecalculation(true);writer.close();}private void writeSheet8(cn.hutool.poi.excel.ExcelWriter writer) {//设置字体Font font = writer.createFont();font.setFontName("黑体");font.setFontHeightInPoints((short) 12);//设置头样式。去除背景setFillPatternCellStyle headCellStyle = writer.getHeadCellStyle();headCellStyle.setFillPattern(FillPatternType.NO_FILL);headCellStyle.setFont(font);headCellStyle.setBorderTop(BorderStyle.NONE);headCellStyle.setBorderRight(BorderStyle.NONE);headCellStyle.setAlignment(HorizontalAlignment.LEFT);List<Sheet8Statistic> data1 = getSheet8StatisticData(1);writer.setSheet(8);//跳过前的几行writer.passRows(4);//写入表1的内容writer.write(data1);//表1写完了,再跳一行writer.passRows(1);//生成第二张表的表头信息。合并单元格writer.merge(5 + data1.size(), 5 + data1.size(), 0, 7, "(三)标题", true);writer.merge(6 + data1.size(), 7 + data1.size(), 0, 0, "", false);writer.merge(6 + data1.size(), 7 + data1.size(), 1, 1, "本期", false);writer.merge(6 + data1.size(), 6 + data1.size(), 2, 3, "上期", false);writer.merge(6 + data1.size(), 6 + data1.size(), 4, 5, "去年同期", false);writer.merge(6 + data1.size(), 6 + data1.size(), 6, 7, "今年以来", false);//跳过刚刚的表头信息行writer.passRows(2);List<Sheet8Statistic> data2 = getSheet8StatisticData(2);data2.add(0, new Sheet8Statistic("无", "本期", "件", "±%", "件", "±%", "件", "±%"));writer.write(data2);}//这里严格按照定义的顺序封装数据。list有几行,就会往下填充几行(当然也可以用map装数据,可以看看官网怎么用的)private List<Sheet8Statistic> getSheet8StatisticData(int tableNo) {}//实体类定义如下public class Sheet8Statistic {/** 地区 */private Object area;/** 本期 */private Object bq;/** 上期 */private Object sq;/** 本期增长率 */private Object bqRate;/** 去年同期 */private Object qntq;/** 去年同期增长率 */private Object qntqRate;/** 今年以来 */private Object jnyl;/** 今年以来增长率 */private Object jnylRate;}

到这里写入的数据都差不多了,有问题或不对的地方欢迎评论指教。利用easyExcel的填充功能,和hutool的写入功能完成一份报表的导出。需要注意的是我这边数据很小无所谓,hutool这个是先把所有数据都写入内存,最后再写入文件的,数据太大就要再处理了,官网也提到了多次写入的办法那些。

用到的依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.10</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><!--/docs hutool有单独的poi包,我这里用的all了。他依赖上面的poi4.1.2 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.14</version></dependency>

下面附上一些用到的常用方法:

四、计算增长率、同比环比、比重等

/*** 计算增长率 2位小数** @param bq 本期* @param sq 上期*/protected String calculateRate(Long bq, Long sq) {DecimalFormat df = new DecimalFormat("0.00");if (sq == 0) {return "0";}return df.format((float) (bq - sq) / sq * 100);}/*** 计算同比、环比、比重** @param bq 本期* @param sq 上期*/protected static String calculateTbHb(Long bq, Long sq) {if (sq == 0) {return "0";}BigDecimal bqBigDecimal = BigDecimal.valueOf(bq);BigDecimal sqBigDecimal = BigDecimal.valueOf(sq);BigDecimal result =(bqBigDecimal.subtract(sqBigDecimal)).divide(sqBigDecimal, 4, BigDecimal.ROUND_UP).multiply(BigDecimal.valueOf(100L)).setScale(2, BigDecimal.ROUND_UP);if (pareTo(BigDecimal.ZERO) > 0) {return "+" + result.doubleValue();} else if (pareTo(BigDecimal.ZERO) < 0) {return String.valueOf(result.doubleValue());} else {return "0";}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。