一、导出报表概述
导出报表是实际开发过程中经常用到的操作,没学过的觉得非常神奇,学过的其实也就那么回事。但是很多程序员其实都是拿来就用,并没有好好思考其中的原理,俗称“CV工程”。个人觉得技术这回事,你自己看懂别人的代码叫了解,能跟着敲出来才算入门。
第一步、创建工具类
首先,我们可以定义一个工具类并定义好静态方法,向方法中传入sheet名称,表头,内容等参数,然后传回HSSFWorkbook对象(Excel文件对象)。
/**
* 导出表格工具类
* @author 梁 钟
*
*/
public class LiangExcelUtil {
/**
* 根据条件生成Excel文件对象HSSFWorkbook
* @param sheetName :sheet名
* @param title: 标题
* @param values: 内容
* @param wb: Excel文件对象
* @return
*/
public static HSSFWorkbook getHSSFWorkbook(String sheetName,String[] title, String[][] values,HSSFWorkbook wb) {
//1.创建一个HSSFWorkbook对象,对应一个Excel文件
if(wb == null) {
wb = new HSSFWorkbook();
}
//2.在HSSFWorkbook中添加一个sheet,对应在Excel中创建一个Sheet
HSSFSheet sheet = wb.createSheet(sheetName);
//第三步,在sheet中添加表头第0行
HSSFRow row = sheet.createRow(0);
//第四步,创建单元格,并设置居中
HSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
HSSFCell cell = null;
//创建标题
for(int i=0;i<title.length;i++) {
cell = row.createCell(i);
cell.setCellValue(title[i]);
cell.setCellStyle(style);
}
//填充内容
for(int i=0;i<values.length;i++) {
row = sheet.createRow(i+1);
for(int j=0;j<values[i].length;j++) {
row.createCell(j).setCellValue(values[i][j]);
}
}
return wb;
}
}
第二步、在接口中根据条件进行查询,并将查询出的结果保存到二维数组中,再使用工具类进行处理后,将返回的HSSFWorkbook 对象写入到响应对象的输出流中。
/**
* 导出领用单报表
* @param response:响应对象
* @param erpApply:包含指定查询条件
*/
@GetMapping("/exportExcel")
public RespBean<Map<String,Object>> exportExcel(HttpServletResponse response,ErpApply erpApply){
//非空校验
if(GuoStringUtil.isEmpty(new String[] {erpApply.getIsDeleted()})) {
return GuoRespBeanUtil.initParamNotNullRespBean();
}
//执行业务逻辑
RespBean<Map<String, Object>> respBean = GuoRespBeanUtil.initRespBean();
Map<String, Object> map = respBean.getBody();
OutputStream os = new ByteOutputStream();
try {
String fileName = "领用单报表"+System.currentTimeMillis()+".xls";
//设置sheet名称
String sheetName = "领用单报表";
//表头
String title[] = {"领用编号","创建时间","最近修改时间","部门名称","是否删除","状态"};
//主体内容
List<ErpApply> list = erpApplyService.selectAllForRelation(erpApply);
String[][] values = new String[list.size()][];
for(int i=0;i<values.length;i++) {
values[i] = new String[title.length];
values[i][0] = list.get(i).getId();
values[i][1] = list.get(i).getCreateTime();
values[i][2] = list.get(i).getUpdateTime();
values[i][3] = list.get(i).getDeptName();
values[i][4] = list.get(i).getIsDeleted().equals("0")?"未删除":"已删除";
//设置状态
String status = list.get(i).getStatus();
switch(status) {
case "0" : status = "未审核";
break;
case "1" : status = "未调拨";
break;
case "2" : status = "未入库";
break;
case "3" : status = "已入库";
break;
case "4" : status = "部分入库";
break;
case "5" : status = "未采购";
break;
case "6" : status = "采购未审核";
break;
case "7" : status = "采购已审核";
break;
}
values[i][5] = status;
}
HSSFWorkbook workbook = LiangExcelUtil.getHSSFWorkbook(sheetName, title, values, null);
fileName = new String(fileName.getBytes(),"ISO8859-1");
//设置响应对象
response.setContentType("application/octet-stream;charset=ISO8859-1");
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
//将Excel对象写入到响应流中
os = response.getOutputStream();
workbook.write(os);
GuoRespBeanUtil.setSuccessRespBean(respBean);
}catch(Exception e) {
e.printStackTrace();
GuoRespBeanUtil.setErrorRespBean(respBean);
}finally {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
GuoRespBeanUtil.setErrorRespBean(respBean);
}
}
return respBean;
}
第三步、在前端页面对后台接口发起请求
/**创建一个导出报表的按钮**/
<button class="layui-btn lf" id="btn_export_excel">导出报表</button>
推荐使用window.open()来开启新的窗口执行下载任务,这样可以实现异步下载。即新的窗口执行下载任务,当前窗口仍可以进行查看等操作。
/**发送导出报表的请求**/
$('#btn_export_excel').on('click',function(){
window.open(baseUrl+"/system/erpApply/exportExcel?
token="+getCookie('info').token+"&isDeleted=0");
});