需求:
查询数据库表数据然后到另一个表找错误的对应字段(就是找到需要填充的单元格所在行的列),对这个单元格进行设置背景色,然后导出数据。
具体的工具类如下
import cn.afterturn.easypoi.excel.annotation.Excel; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.IndexedColors; import java.io.FileOutputStream; import java.lang.reflect.Field; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 导出Excel需要的工具类 * @Auther 张德昌 */ public class ExportDataUtils { /** * 传入一个list数据 得到list数据中所有错误数据总条数 * 和list数据的总条数 * @param list list Object类型 * @return 返回一个String字符串(2-10) 2表示list数据中错误数据的总条数 10表示list数据总数 */ public static String getTotalNum(List list){ /** * 实现具体思路: * 定义两个变量存储 错误总数 和 list数据总数 * 遍历list通过反射得到类字段名称和字段值 * 然后判断excepetionName字段有值(有值代表这个list数据中有错误数据) 然后给变量+1 * 最后得到所有的总错误数据和list长度 进行返回 * 返回结果(2-10)2错误数据总数 10 list数据总数 */ String str=""; int total = 0; if(list!=null) { total = list.size(); } int num = 0; try{ for(int a= 0;a<list.size();a++){ Object ds= list.get(a); Class cls = ds.getClass(); Field[] fields = cls.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; f.setAccessible(true); if (f.getName().equals("excepetionName")) { Object obj = f.get(ds); if (obj != null) { ++num; break; } } } } }catch (Exception e){ e.printStackTrace(); } str=num+"-"+total; return str; } /** * 导出excel实现方法 * @param list list Object类型 * @param name 创建sheet表名字 * @param book HSSFWorkbook * @param o Object类型 * @param fileName 文件保存名称 * @throws Exception */ public static void exportAll(List<Object> list, String name, HSSFWorkbook book, Object o, String fileName) throws Exception{ /** * 实现方法: * 创建excel表时候 先生成一个sheet文件名字 * sheet表第一行创建的都是标题内容 不是具体数据值 * 定义两个style 样式 * style1是给当前有问题的行做颜色标示 * style2是给当前有问题的行的具体问题字段做颜色标示 * 不创建错误字段描述这个字段 * 第一行创建完成之后 创建下一行 然后调用reflect方法填充下一行的数据 * 最后保存到一个文件 */ HSSFSheet sheet = book.createSheet(name); CellStyle style1 = book.createCellStyle(); CellStyle style2 = book.createCellStyle(); CellStyle style3 = book.createCellStyle(); HSSFRow header=sheet.createRow(0); Class cls = o.getClass(); Field[] fields = cls.getDeclaredFields(); for (int a = 0; a < fields.length; a++) { Excel attr = fields[a].getAnnotation(Excel.class); if(attr.name().equals("错误字段描述")){ continue; } header.createCell(a-1).setCellValue(attr.name()); style3.setFillPattern(FillPatternType.SOLID_FOREGROUND); style3.setFillForegroundColor(IndexedColors.PALE_BLUE.index); setBorder(style3); header.getCell(a-1).setCellStyle(style3); } for(int i= 0;i<list.size();i++){ Object ds= list.get(i); header = sheet.createRow(i+1); reflect(ds,header,book,style1,style2); } FileOutputStream fos; try { fos = new FileOutputStream("/Users/zhangdechang/datePath/other/"+fileName+".xls"); book.write(fos); fos.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 填充单元格数据并设置某个单元格的颜色 * @param e Object类型 * @param header 行 * @param wb HSSFWorkbook * @param style1 当前有问题的行做颜色标示 * @param style2 当前有问题的行的具体问题字段做颜色标示 * @return HSSFRow * @throws Exception */ public static HSSFRow reflect(Object e,HSSFRow header,HSSFWorkbook wb,CellStyle style1,CellStyle style2) throws Exception{ /** * 实现思路: *定义一个map变量存储当前这个实体类的错误字段 * 通过反射得到类字段名称和字段值 * 如果字段是excepetionName 并且值不是空的就吧里面的值用, 分割并填充到map * 如果字段名是excepetionName excel就不存储这个值跳过 * 把得到的值填充到当前单元格 * 把当前的字段名称变成与数据库相同的名称到map里面去判断有没有这个名称 * 如果有就把当前的行和当前的单元格分别设置不同颜色展示 * 最后map初始化 并返回 */ Map<String,String> mp= new HashMap<>(); Class cls = e.getClass(); Field[] fields = cls.getDeclaredFields(); for(int i=0; i<fields.length; i++){ Field f = fields[i]; f.setAccessible(true); if(f.getName().equals("excepetionName")){ Object obj= f.get(e); if(obj!=null){ String str = obj.toString(); String split[] = str.split(","); for(String s:split){ mp.put(s,s); } } } Object obj= f.get(e); String name = f.getName(); if(name.equals("excepetionName")){ continue; } header.createCell(i-1).setCellValue(obj==null?"":obj.toString()); setBorder(style1); header.getCell(i-1).setCellStyle(style1); String underlineName= TransferUtil.camelToUnderline(name); if(mp.size()>0) { style1.setFillPattern(FillPatternType.SOLID_FOREGROUND); style1.setFillForegroundColor(IndexedColors.YELLOW.index); setBorder(style1); header.getCell(i-1).setCellStyle(style1); if (mp.containsKey(underlineName)) { style2.setFillPattern(FillPatternType.SOLID_FOREGROUND); style2.setFillForegroundColor(IndexedColors.RED.index); setBorder(style2); header.getCell(i-1).setCellStyle(style2); } } } mp=new HashMap<>(); return header; } /** * 设置单元格边框 * @param style */ public static void setBorder(CellStyle style){ //下边框 style.setBorderBottom(HSSFCellStyle.BORDER_THIN); //左边框 style.setBorderLeft(HSSFCellStyle.BORDER_THIN); //上边框 style.setBorderTop(HSSFCellStyle.BORDER_THIN); //右边框 style.setBorderRight(HSSFCellStyle.BORDER_THIN); } }
对应的实体类 :实体类
@TableName("gz_department_area") public class DepartmentArea extends BaseEntity<DepartmentArea> { private static final long serialVersionUID = 1L; /** * 主键 */ private String id; /** * 所属部门 */ @TableField("sys_org_code") private String sysOrgCode; /** * 单位名称 */ @TableField("org_nm") private String orgNm; /** * gz_area表主键ID */ @TableField("gz_area_id") private Integer gzAreaId; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getSysOrgCode() { return sysOrgCode; } public void setSysOrgCode(String sysOrgCode) { this.sysOrgCode = sysOrgCode; } public String getOrgNm() { return orgNm; } public void setOrgNm(String orgNm) { this.orgNm = orgNm; } public Integer getGzAreaId() { return gzAreaId; } public void setGzAreaId(Integer gzAreaId) { this.gzAreaId = gzAreaId; } @Override protected Serializable pkVal() { return this.id; } @Override public String toString() { return "DepartmentArea{" + ", id=" + id + ", sysOrgCode=" + sysOrgCode + ", orgNm=" + orgNm + ", gzAreaId=" + gzAreaId + "}"; }
Controller调用方法
@RequestMapping(value = "/exportExcel") public void list(String[] orgCode, HttpServletResponse response,String year){ /** * 查询gz_department_area表得到所有数据 * 遍历每个数据的编号去9个表里面分别查对应的数据 * 然后调用ExportDataUtils 工具类来生成对应的excel */ try { if(orgCode.length<=0){ orgCode=null; } List<DepartmentArea> departmentAreaList= departmentAreaService.getDepartmentAreaAll(orgCode); OutputStream out = response.getOutputStream(); ZipOutputStream zipOutputStream = new ZipOutputStream(out); response.setContentType("application/octet-stream "); // 表示不能用浏览器直接打开 response.setHeader("Connection", "close"); response.setHeader("Content-type", "application-download"); // 告诉客户端允许断点续传多线程连接下载 response.setHeader("Accept-Ranges", "bytes"); response.setHeader("Content-Disposition","attachment;filename="); response.setCharacterEncoding("UTF-8"); List<Map<HSSFWorkbook,String>> lists = new ArrayList<>(); if(departmentAreaList!=null) { if (departmentAreaList.size() > 0) { for (DepartmentArea departmentArea : departmentAreaList) { cachedThreadPool.execute(new Runnable() { @Override public void run() { try { Map<HSSFWorkbook, String> mp = new HashMap<>(); HSSFWorkbook book = new HSSFWorkbook(); String code = departmentArea.getSysOrgCode(); String filesName = departmentArea.getOrgNm(); List list = dataAssetsService.searchAll(code, year); List ecsList = ecsCloudResourceService.searchEcsCloudResourceAll(code, year); List eqpInfos = eqpInfoService.searchEqpInfoAll(code, year); List cloudResources = ossCloudResourceService.searchOssCloudResourceAll(code, year); List rdsCloudResouces = rdsCloudResouceService.searchRdsCloudResouceAll(code, year); List slbCloudResources = slbCloudResourceService.searchSlbCloudResourceAll(code, year); List softInfos = softInfoService.searchSoftInfoAll(code, year); List sysInfos = sysInfoService.searchSysInfoAll(code, year); List zyJfqks = zyJfqkService.searchZyJfqkAll(code, year); if (sysInfos != null) { String num = ExportDataUtils.getTotalNum(sysInfos); ExportDataUtils.exportAll(sysInfos, "信息系统清单" + num, book, new SysInfo(), filesName, response, zipOutputStream); } if (zyJfqks != null) { String num = ExportDataUtils.getTotalNum(zyJfqks); ExportDataUtils.exportAll(zyJfqks, "自有机房情况" + num, book, new ZyJfqk(), filesName, response, zipOutputStream); } if (eqpInfos != null) { String num = ExportDataUtils.getTotalNum(eqpInfos); ExportDataUtils.exportAll(eqpInfos, "硬件资产清单" + num, book, new EqpInfo(), filesName, response, zipOutputStream); } if (softInfos != null) { String num = ExportDataUtils.getTotalNum(softInfos); ExportDataUtils.exportAll(softInfos, "软件资产清单" + num, book, new SoftInfo(), filesName, response, zipOutputStream); } if (list != null) { String num = ExportDataUtils.getTotalNum(list); ExportDataUtils.exportAll(list, "数据资产描述" + num, book, new DataAssets(), filesName, response, zipOutputStream); } if (ecsList != null) { String num = ExportDataUtils.getTotalNum(ecsList); ExportDataUtils.exportAll(ecsList, "ECS云资源清单" + num, book, new EcsCloudResource(), filesName, response, zipOutputStream); } if (rdsCloudResouces != null) { String num = ExportDataUtils.getTotalNum(rdsCloudResouces); ExportDataUtils.exportAll(rdsCloudResouces, "RDS云资源清单" + num, book, new RdsCloudResouce(), filesName, response, zipOutputStream); } if (slbCloudResources != null) { String num = ExportDataUtils.getTotalNum(slbCloudResources); ExportDataUtils.exportAll(slbCloudResources, "SLB云资源清单" + num, book, new SlbCloudResource(), filesName, response, zipOutputStream); } if (cloudResources != null) { String num = ExportDataUtils.getTotalNum(cloudResources); ExportDataUtils.exportAll(cloudResources, "OSS云资源清单" + num, book, new OssCloudResource(), filesName, response, zipOutputStream); } mp.put(book, filesName); lists.add(mp); } catch (Exception e) { e.printStackTrace(); } } }); } } cachedThreadPool.shutdown(); boolean isFlag = true; while (isFlag) { if (cachedThreadPool.isTerminated()) { cachedThreadPool=Executors.newFixedThreadPool(100); //具体操作 ExportDataUtils.Exprt(lists, zipOutputStream); isFlag = false; } } } }catch (Exception e){ e.printStackTrace(); } }导出excel效果
14-15意思就是 一共有15条数据 有14条数据内容有问题
把有问题的字段用红色背景标注出来