摘要:在javaWeb开发中,会经常遇到导出业务数据的业务需求,导出Excel最常用的技术就是poi,对于简单的业务,我们可以动态的生成一个Excel文件,但对于复杂的业务,我们可以通过使用读取Excel模板的,然后往里面填充数据的方式,下载文件。
最终下载的Excel截图如下图所示(部分截图),数据均为测试数据:
文章图片
1.准备Excel模板文件文件 根据导出业务需求,创建Excel模板文件,并将文件放入到webapp中的resources目录下,如下图所示 (部分截图)。
文章图片
文章图片
2.获取Excel导出的fileName和业务数据 在导出数据前,需要设置Excel下载后的文件名称以及业务数据,然后将数据写入到Excel模板中。
try {
JSONObject excelNameAndData = https://www.it610.com/article/service.getExcelNameAndData();
fileName = excelNameAndData.getString("fileName");
dataList = excelNameAndData.getObject("dataList", List.class);
} catch (Exception e) {
logger.error("message {}","Excel数据获取失败:" + e.getMessage());
return;
}
3.设置response相关属性
response.setContentType("application/vnd.ms-excel");
response.setHeader("content-disposition", "attachment;
filename=" + fileName + ".xls");
4.获取Excel模板的HSSFWorkbook对象 【javaWeb中使用Excel模板导出业务数据(包含复杂单元格动态合并操作)+附源码】在使用Excel模板的时候,需要获取到模板的输入流,然后根据此输入流,创建出HSSFWorkbook对象,在数据插入到模板文件后,在刷到浏览器上。
// 拿到模板文件
String tplPath = request.getSession().getServletContext().getRealPath("resources/template/");
String filePath = tplPath + "/prepareRankTemplate.xls";
try (FileInputStream fIn = new FileInputStream(new File(filePath));
OutputStream fOut = response.getOutputStream()) {
HSSFWorkbook tpWorkbook = new HSSFWorkbook(fIn);
workbook = ExcelExportUtil.exportExcel(tpWorkbook, dataList);
if (workbook != null) {
workbook.write(fOut);
}
} catch (Exception e) {
logger.error(e.getMessage());
return;
}
5.将数据插入到Excel中 由于模板文件的标题占用了2行,因此我们在插入数据时,从第三行开始。在循环数据时,首先获取到这个用户下面数据条目(假如有3条),然后将序号、姓名列的单元格进行合并,插入序号、年级等值,然后在遍历这个用户下的数据条目,分别插入年级学科、应备等数据
/**
* 获取Workbook对象
*
*/
private static HSSFWorkbook getPrepareTopExcel(HSSFWorkbook tempWorkbook, List list) {
// 创建一个workbook 对应一个excel应用文件
HSSFWorkbook workBook = tempWorkbook;
HSSFSheet sheet = workBook.getSheetAt(0);
ExcelInternalUtil exportUtil = new ExcelInternalUtil(workBook, sheet);
HSSFCellStyle bodyStyle = exportUtil.getBodyStyle();
HSSFCell cell = null;
CellRangeAddress regionIndex = null;
CellRangeAddress regionName = null;
//纵向合并序号、姓名等单元格的起始行数
int startRegionRowNum = 2;
PersonPrepareRanNewVo personPrepareRanNewVo = null;
List prepareRankVos = null;
// 构建表体数据
for (int i = 0;
i < list.size();
i++) {
// 创建行
HSSFRow bodyRow = sheet.getRow(startRegionRowNum);
if (bodyRow == null) {
bodyRow = sheet.createRow(startRegionRowNum);
}
personPrepareRanNewVo = (PersonPrepareRanNewVo) list.get(i);
prepareRankVos = personPrepareRanNewVo.getPrepareRankVos();
//单元格合并
regionIndex = new CellRangeAddress(startRegionRowNum, startRegionRowNum + prepareRankVos.size() - 1, 0, 0);
regionName = new CellRangeAddress(startRegionRowNum, startRegionRowNum + prepareRankVos.size() - 1, 1, 1);
sheet.addMergedRegion(regionIndex);
sheet.addMergedRegion(regionName);
//序号
cell = bodyRow.createCell(0);
cell.setCellValue(String.valueOf(i + 1));
//姓名
cell = bodyRow.createCell(1);
cell.setCellValue(personPrepareRanNewVo.getUserName());
//设置合并后的单元格样式
exportUtil.setRegionStyle(regionIndex, bodyStyle);
exportUtil.setRegionStyle(regionName, bodyStyle);
initPrepareRankTopData(sheet, prepareRankVos, startRegionRowNum, bodyStyle);
startRegionRowNum += prepareRankVos.size();
}
return workBook;
}
填充年级学科、备课信息等数据
/**
* 向Excel中填充个人备课数据
*
* @param sheet Excel sheet
* @param prepareRankVos 个人备课数据
* @param startRowNum 数据插入起始行
* @param bodyStyle 单元格样式
*/
private static void initPrepareRankTopData(HSSFSheet sheet, List prepareRankVos, int startRowNum, HSSFCellStyle bodyStyle) {
HSSFCell cell = null;
HSSFRow bodyRow = null;
for (PersonPrepareRankVo prepareRankVo : prepareRankVos) {
bodyRow = sheet.getRow(startRowNum);
if (bodyRow == null) {
bodyRow = sheet.createRow(startRowNum);
}
startRowNum++;
for (int j = 0;
j < 10;
j++) {
cell = bodyRow.createCell(j + 2);
Object val = getCellValues(j, prepareRankVo);
if (val == null) {
val = "";
}
cell.setCellStyle(bodyStyle);
cell.setCellValue(val.toString());
}
}
}
获取并处理年级学科、备课信息数据
/**
*从个人备课本中取出各个类型的数据
* @param index
* @param prepareRankVo
* @return
*/
private static Object getCellValues(int index, PersonPrepareRankVo prepareRankVo) {
Object val = null;
if (index == 0) {
//年级学科
val = prepareRankVo.getGradeStr() + prepareRankVo.getSubjectStr();
} else if (index == 1) {
//应备
val = prepareRankVo.getMustCount();
} else if (index == 2) {
//实备
val = prepareRankVo.getPrepareNum();
} else if (index == 3) {
//备课完成率
val = prepareRankVo.getFinishRate();
try {
val = NumUtils.percent(val.toString());
} catch (Exception e) {
logger.error("message {}", "备课完成率转换异常:" + e);
val = "";
}
} else if (index == 4) {
//导学案
val = prepareRankVo.getDaoxueNum();
} else if (index == 5) {
//教案
val = prepareRankVo.getJiaoAnNum();
} else if (index == 6) {
//课件
val = prepareRankVo.getKejianNum();
} else if (index == 7) {
//微课
val = prepareRankVo.getWeikeNum();
} else if (index == 8) {
//习题
val = prepareRankVo.getXitiNum();
} else {
//其他
val = prepareRankVo.getQitaNum();
}
return val;
}
6.附件源码 https://download.csdn.net/download/qq_34976024/10835811
备注:附件的代码中并不包含博客中的代码片段,也没有实现单元格动态合并操作,属于一个简化版,只演示了模板的用法,如果需要实现动态合并,可在附件的基础上阅读博客中第5部分的内容,自行实现。动态合并的demo源码后续补充。
附件源码运行后,下载Excel的文件截图如下图所示,数据均为测试数据。
文章图片
推荐阅读
- javaweb|基于Servlet+jsp+mysql开发javaWeb学生成绩管理系统
- JavaWeb|JavaWeb学习——CSS
- JavaWeb|JavaWeb学习——用户注册(14)
- 验证码 注意一点存session时
- Spring Boot 版本升级到2
- html模仿淘宝按钮
- 获取客户端IP地址
- Tomcat服务器映射图片,文件地址
- JavaWeb|电商后台管理系统项目后台项目的环境安装及配置