需求:
查詢數據庫表數據然後到另一個表找錯誤的對應字段(就是找到需要填充的單元格所在行的列),對這個單元格進行設置背景色,然後導出數據。
具體的工具類如下
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條數據內容有問題
把有問題的字段用紅色背景標註出來