需求:
查询数据库表数据然后到另一个表找错误的对应字段(就是找到需要填充的单元格所在行的列),对这个单元格进行设置背景色,然后导出数据。
具体的工具类如下
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条数据内容有问题
把有问题的字段用红色背景标注出来