93人参与 • 2025-03-08 • Java
公司有个报表需求是根据指定日期范围导出指定数据,并且要根据不同逻辑生成两个sheet,这个日期影响的是列数而不是行数,即行的数量和列的数量都是动态变化的,根据用户的选择动态生成的,这个问题花了不少时间才解决的,这边记下笔记。
动态生成30个列,两张sheet

动态生成1个列,两张sheet

我们公司使用的版本是3.2.0,我们项目没有引入所有模块,只用到了base和annotation
<dependency> <groupid>cn.afterturn</groupid> <artifactid>easypoi-base</artifactid> <version>3.2.0</version> <exclusions> <exclusion> <groupid>org.slf4j</groupid> <artifactid>slf4j-api</artifactid> </exclusion> <exclusion> <groupid>org.apache.commons</groupid> <artifactid>commons-lang3</artifactid> </exclusion> </exclusions> </dependency> <dependency> <groupid>cn.afterturn</groupid> <artifactid>easypoi-annotation</artifactid> <version>3.2.0</version> </dependency>
定义表格样式
/**
* 定义表格样式
*
* @param start 查询起始日期
* @param end 查询结束日期
* @return java.util.list<cn.afterturn.easypoi.excel.entity.params.excelexportentity>
* @author huan
* @date 2019/6/21
* @since 2.8.2
*/
private list<excelexportentity> setexportexcelstyle(datetime start, datetime end) {
//定义表格列名,该集合存放的就是表格的列明,每个对象就是表格中的一列
list<excelexportentity> modellist = new arraylist<excelexportentity>();
//该对象就是定义列属性的对象
excelexportentity excelentity = null;
//定义第一个列
excelentity = new excelexportentity("企业全称", "companyname");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
//定义第二个列
excelentity = new excelexportentity("企业简称", "companyshortname");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
//定义第三个列,这里指定了日期显示格式
excelentity = new excelexportentity("认证日期", "opendate");
excelentity.setwidth(20);
excelentity.setheight(10);
excelentity.setformat("yyyy-mm-dd");
modellist.add(excelentity);
//定义第四个列,这边就是动态生成的,跟用用户选择的日期范围,动态生成列的数量
excelentity = new excelexportentity(null, "recorddate");
//设置一个集合,存放动态生成的列
list<excelexportentity> modellistchild = new arraylist<excelexportentity>();
start = dateutils.getdatezerotime(start);
while (start.isbefore(end)) {
string date = start.tostring("yyyy-mm-dd");
modellistchild.add(new excelexportentity(date, date, 15));
start = start.plusdays(1);
}
//日期按从小到大顺序排序,这里用了最简单的冒泡排序
for (int i = 0; i < modellistchild.size(); i++) {
for (int j = 0; j < modellistchild.size(); j++) {
string e1 = modellistchild.get(i).getkey().tostring();
string e2 = modellistchild.get(j).getkey().tostring();
if (e1.compareto(e2) < 0) {
excelexportentity x1 = modellistchild.get(i);
excelexportentity x2 = modellistchild.get(j);
modellistchild.set(j, x1);
modellistchild.set(i, x2);
}
}
}
//将定义好的字列放到父列中
excelentity.setlist(modellistchild);
modellist.add(excelentity);
//定义第五个列
excelentity = new excelexportentity("应当使用天数", "shoulduseday");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
//定义第六个列
excelentity = new excelexportentity("实际使用天数", "actualuseday");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
//定义第七个列
excelentity = new excelexportentity("使用率", "rate");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
//定义第八个列
excelentity = new excelexportentity("推荐人", "commandman");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
//定义第九个列
excelentity = new excelexportentity("拓客", "tk");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
//定义第十个列
excelentity = new excelexportentity("对接人", "connector");
excelentity.setwidth(20);
excelentity.setheight(10);
modellist.add(excelentity);
return modellist;
}
定义表格数据
private list<map<string, object>> getdata(analysestockquery analysestockquery, boolean type) {
//获取数据源
arraylist<analysestockexportdto> dtolist = listdetaildatawithnum(analysestockquery, type);
list<map<string, object>> datalist = new arraylist<>();
//存储没一行中的日期数据
list<map<string, object>> datalistchild = null;
//存储表格中的每一行数据
map<string, object> mapparent = null;
//数据排序
dtolist.sort(new exportcomparator());
//定义表格数据
for (analysestockexportdto dto : dtolist) {
mapparent = new hashmap(7);
//这边只要和定义表格样式的时候 名称一致就行 我这边因为有三个字段不需要我这边后台生成,所以就没有设置默认值了
mapparent.put("companyname", dto.getcompanyname());
mapparent.put("companyshortname", dto.getcompanyshortname());
mapparent.put("opendate", dto.getopendate());
mapparent.put("shoulduseday", dto.getshoulduseday());
mapparent.put("actualuseday", dto.getactualuseday());
mapparent.put("rate", dto.getrate());
map<string, object> map = dto.getdatelist();
datalistchild = new arraylist<>();
datalistchild.add(map);
mapparent.put("recorddate", datalistchild);
datalist.add(mapparent);
}
return datalist;
}
主体方法
/**
* 报表导出
*
* @param analysestockquery analysestockquery
* @param response response
* @return javax.servlet.http.httpservletresponse
* @author huan
* @date 2019/6/21
* @since 2.8.2
*/
public httpservletresponse exportstock(analysestockquery analysestockquery, httpservletresponse response) {
try {
//设置默认查询日期
analysestockquery = setdefaultquerydate(analysestockquery);
//参数校验
checklistdetaildataparam(analysestockquery);
//日期格式化
datetime start = new datetime().withdate(new localdate(analysestockquery.getquerystartdate()));
datetime end = new datetime().withdate(new localdate(analysestockquery.getquerylastdate()));
//定义表格样式
list<excelexportentity> modellist = setexportexcelstyle(start, end);
//定义表格名称
string filename = urlencoder.encode("客户库存使用统计表-" + start.tostring("yyyy年mm月dd日") + "~" + end.tostring("yyyy年mm月dd日"), "utf-8");
// sheet1样式
exportparams sheet1exportparams = new exportparams();
// 设置sheet得名称
sheet1exportparams.setsheetname("入库统计");
// 创建sheet1使用得map
map<string, object> sheet1exportmap = new hashmap<>();
// title的参数为exportparams类型,目前仅仅在exportparams中设置了sheetname
sheet1exportmap.put("title", sheet1exportparams);
//sheet1样式
sheet1exportmap.put("entitylist", modellist);
//sheet1中要填充得数据,true表示查询入库数据,false表示查询易签待入库数据
sheet1exportmap.put("data", getdata(analysestockquery, true));
//sheet2设置
exportparams sheet2exportparams = new exportparams();
sheet2exportparams.setsheetname("易签待入库统计");
map<string, object> sheet2exportmap = new hashmap<>();
sheet2exportmap.put("title", sheet2exportparams);
sheet2exportmap.put("entitylist", modellist);
sheet2exportmap.put("data", getdata(analysestockquery, false));
// 将sheet1、sheet2使用得map进行包装
list<map<string, object>> sheetslist = new arraylist<>();
sheetslist.add(sheet1exportmap);
sheetslist.add(sheet2exportmap);
// 执行方法
workbook workbook = exportexcel(sheetslist, exceltype.hssf);
//设置response
response.setheader("content-disposition", "attachment;filename=" + filename + ".xls");
//设置编码格式
response.setcharacterencoding("gbk");
//将表格内容写到输出流中并刷新缓存
@cleanup servletoutputstream out = response.getoutputstream();
workbook.write(out);
out.flush();
workbook.close();
} catch (filenotfoundexception e) {
log.debug("filenotfoundexception:{}", e.getmessage());
} catch (unsupportedencodingexception e) {
log.debug("unsupportedencodingexception:{}", e.getmessage());
} catch (ioexception e) {
log.debug("ioexception:{}", e.getmessage());
}
return response;
}
导出excel
/**
* 导出ecel
*
* @return org.apache.poi.ss.usermodel.workbook
* @author zhuyongsheng
* @date 2019/11/6
*/
private static workbook exportexcel(list<map<string, object>> list) {
workbook workbook = new hssfworkbook();
for (map<string, object> map : list) {
myexcelexportservice service = new myexcelexportservice();
service.createsheetwithlist(workbook, (exportparams) map.get("title"), exportparams.class,
(list<excelexportentity>) map.get("entitylist"), (collection<?>) map.get("data"));
}
return workbook;
}
自定义导出逻辑
package com.ccb.service.analyse;
import cn.afterturn.easypoi.excel.annotation.exceltarget;
import cn.afterturn.easypoi.excel.entity.exportparams;
import cn.afterturn.easypoi.excel.entity.enmus.exceltype;
import cn.afterturn.easypoi.excel.entity.params.excelexportentity;
import cn.afterturn.easypoi.excel.export.excelexportservice;
import cn.afterturn.easypoi.exception.excel.excelexportexception;
import cn.afterturn.easypoi.exception.excel.enums.excelexportenum;
import cn.afterturn.easypoi.util.poipublicutil;
import lombok.extern.slf4j.slf4j;
import org.apache.poi.ss.usermodel.workbook;
import java.lang.reflect.field;
import java.util.arraylist;
import java.util.collection;
import java.util.list;
/**
* 自定义下导出逻辑
* @author huan
* @version 2.8.2
* @date 2019/7/5
*/
@slf4j
public class myexcelexportservice extends excelexportservice {
public void createsheetwithlist(workbook workbook, exportparams entity, class<?> pojoclass, list<excelexportentity> entitylist, collection<?> dataset) {
if (logger.isdebugenabled()) {
logger.debug("excel export start ,class is {}", pojoclass);
logger.debug("excel version is {}",
entity.gettype().equals(exceltype.hssf) ? "03" : "07");
}
if (workbook == null || entity == null || pojoclass == null || dataset == null) {
throw new excelexportexception(excelexportenum.parameter_error);
}
try {
list<excelexportentity> excelparams = entitylist;
// 得到所有字段
field[] fileds = poipublicutil.getclassfields(pojoclass);
exceltarget etarget = pojoclass.getannotation(exceltarget.class);
string targetid = etarget == null ? null : etarget.value();
getallexcelfield(entity.getexclusions(), targetid, fileds, excelparams, pojoclass,
null, null);
//获取所有参数后,后面的逻辑判断就一致了
createsheetformap(workbook, entity, excelparams, dataset);
} catch (exception e) {
logger.error(e.getmessage(), e);
throw new excelexportexception(excelexportenum.export_error, e.getcause());
}
}
}以上就是利用easypoi实现多sheet和列数的动态生成的详细内容,更多关于easypoi生成多sheet和列数的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论