效果圖
主要代碼
package cn.com.gtmc.glaf2.framework.utils;
import org.apache.poi.hssf.usermodel.;
import org.apache.poi.ss.usermodel.;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
/**
-
Copyright (C), 2015-2017, its
-
FileName: PoiExportAutoMergeRowAndColumn
-
Author: hdk
-
Date: 2020-10-28 0:00
-
Description: 基於poi動態導出合並頭,合並列工具類,
-
mergeRow 合並行
-
genMergeCellByContent 合並頭
-
History:
-
-
作者姓名 修改時間 版本號 描述
*/
public class PoiExportAutoMergeRowAndColumn {
private static final Logger logger = LoggerFactory.getLogger(PoiExportAutoMergeRowAndColumn.class);public static
void exportTest(String excelName, List list, LinkedHashMap<String, Object> fieldMap) { // 設置默認文件名為當前時間:年月日時分秒 if (excelName == null || excelName == "") { excelName = new SimpleDateFormat("yyyyMMddhhmmss").format( new Date()).toString(); } try { //創建一個WorkBook,對應一個Excel文件 HSSFWorkbook wb = new HSSFWorkbook(); //在Workbook中,創建一個sheet,對應Excel中的工作薄(sheet) HSSFSheet sheet = wb.createSheet(excelName); //創建單元格,並設置值表頭 設置表頭居中 HSSFCellStyle style = wb.createCellStyle(); //創建一個居中格式 //style.setAlignment(ALIGN_CENTER); style.setAlignment(HorizontalAlignment.CENTER); // 填充工作表 fillSheet(sheet, list, fieldMap, style); FileOutputStream dd = new FileOutputStream("c://test.xls"); //將文件輸出 OutputStream ouputStream = dd; wb.write(ouputStream); ouputStream.flush(); ouputStream.close(); } catch (Exception e) { logger.info("導出Excel失敗!"); logger.error(e.getMessage()); }
}
/**
-
根據字段名獲取字段對象
-
@param fieldName 字段名
-
@param clazz 包含該字段的類
-
@return 字段
*/
public static Field getFieldByName(String fieldName, Class<?> clazz) {
// logger.info("根據字段名獲取字段對象:getFieldByName()");
// 拿到本類的所有字段
Field[] selfFields = clazz.getDeclaredFields();// 如果本類中存在該字段,則返回
for (Field field : selfFields) {
//如果本類中存在該字段,則返回
if (field.getName().equals(fieldName)) {
return field;
}
}// 否則,查看父類中是否存在此字段,如果有則返回
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null && superClazz != Object.class) {
//遞歸
return getFieldByName(fieldName, superClazz);
}// 如果本類和父類都沒有,則返回空
return null;
}
/**
-
根據字段名獲取字段值
-
@param fieldName 字段名
-
@param o 對象
-
@return 字段值
-
@throws Exception 異常
*/
public static Object getFieldValueByName(String fieldName, Object o)
throws Exception {if (o instanceof HashMap) {
return ((HashMap) o).get(fieldName);
}// logger.info("根據字段名獲取字段值:getFieldValueByName()");
Object value = null;
//根據字段名得到字段對象
Field field = getFieldByName(fieldName, o.getClass());//如果該字段存在,則取出該字段的值
if (field != null) {
field.setAccessible(true);//類中的成員變量為private,在類外邊使用屬性值,故必須進行此操作
value = field.get(o);//獲取當前對象中當前Field的value
} else {
throw new Exception(o.getClass().getSimpleName() + "類不存在字段名 "
+ fieldName);
}return value;
}
/**
-
根據帶路徑或不帶路徑的屬性名獲取屬性值,即接受簡單屬性名,
-
如userName等,又接受帶路徑的屬性名,如student.department.name等
-
@param fieldNameSequence 帶路徑的屬性名或簡單屬性名
-
@param o 對象
-
@return 屬性值
-
@throws Exception 異常
*/
public static Object getFieldValueByNameSequence(String fieldNameSequence,
Object o) throws Exception {
// logger.info("根據帶路徑或不帶路徑的屬性名獲取屬性值,即接受簡單屬性名:getFieldValueByNameSequence()");
Object value = null;// 將fieldNameSequence進行拆分
String[] attributes = fieldNameSequence.split("\.");
if (attributes.length == 1) {
value = getFieldValueByName(fieldNameSequence, o);
} else {
// 根據數組中第一個連接屬性名獲取連接屬性對象,如student.department.name
Object fieldObj = getFieldValueByName(attributes[0], o);
//截取除第一個屬性名之后的路徑
String subFieldNameSequence = fieldNameSequence
.substring(fieldNameSequence.indexOf(".") + 1);
//遞歸得到最終的屬性對象的值
value = getFieldValueByNameSequence(subFieldNameSequence, fieldObj);
}
return value;
}
/**
-
向工作表中填充數據
-
@param sheet excel的工作表名稱
-
@param list 數據源
-
@param fieldMap 中英文字段對應關系的Map
-
@param style 表格中的格式
-
@throws Exception 異常
*/
public staticvoid fillSheet(HSSFSheet sheet, List list,
LinkedHashMap<String, Object> fieldMap, HSSFCellStyle style) throws Exception {
// logger.info("向工作表中填充數據:fillSheet()");
// 定義存放英文字段名和中文字段名的數組
String[] enFields = new String[fieldMap.size()];
String[] cnFields = new String[fieldMap.size()];// 填充數組
int count = 0;
for (Map.Entry<String, Object> entry : fieldMap.entrySet()) {
enFields[count] = entry.getKey();
cnFields[count] = entry.getValue().toString();
count++;
}
int firstRow = 0;
int lastRow = 3;
int firstCol = 0;
int lastCol = 0;//在sheet中添加表頭第0行,注意老版本poi對Excel的行數列數有限制short
HSSFRow row = sheet.createRow((int) 0);
// 填充表頭
for (int i = 0; i < cnFields.length; i++) {
String val = cnFields[i];
HSSFCell cell = null;
String[] split = val.split("-");
if (split.length == 4) {
genMergeHeader(split, sheet, i, style);//生成合並列
continue;
}cell = row.createCell(i); cell.setCellValue(val); if (split.length != 4) { firstCol = i; lastCol = i; CellRangeAddress cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol); sheet.addMergedRegion(cellRangeAddress); RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet); RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet); RegionUtil.setBorderLeft(BorderStyle.THIN, cellRangeAddress, sheet); RegionUtil.setBorderRight(BorderStyle.THIN, cellRangeAddress, sheet); RegionUtil.setBorderTop(BorderStyle.THIN, cellRangeAddress, sheet); } HSSFFont font = sheet.getWorkbook().createFont(); style.setAlignment(HorizontalAlignment.CENTER); font.setFontName("宋體"); font.setFontHeightInPoints((short) 12);// 設置字體大小 //font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); style.setFont(font); style.setWrapText(true); style.setVerticalAlignment(VerticalAlignment.CENTER); style.setBorderBottom(BorderStyle.THIN); //下邊框 style.setBorderLeft(BorderStyle.THIN);//左邊框 style.setBorderTop(BorderStyle.THIN);//上邊框 style.setBorderRight(BorderStyle.THIN);//右邊框 style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); cell.setCellStyle(style); sheet.setColumnWidth(i, val.length() * 1000); sheet.autoSizeColumn(i);
}
//todo合並單元格列頭
genMergeCellByContent(0, 2, 6, 56, sheet);
// 填充內容
String[] arrayList = new String[enFields.length];
HashMap hashMap = new HashMap();for (int index = 0; index < list.size(); index++) {
row = sheet.createRow(index + 4);// 獲取單個對象 T item = list.get(index); for (int i = 0; i < enFields.length; i++) { Object objValue = getFieldValueByNameSequence(enFields[i], item); String fieldValue = objValue == null ? "" : objValue.toString(); row.createCell(i).setCellValue(fieldValue); }
}
for (Object o : hashMap.keySet()) {
Integer i = (Integer) o;
List o1 = (ArrayList) hashMap.get(o);
CellRangeAddress cellRangeAddress = new CellRangeAddress((Integer) o1.get(0) + 3, (Integer) o1.get(o1.size() - 1) + 4, i, i);
sheet.addMergedRegionUnsafe(cellRangeAddress);
}
}
/**
-
根據內容合並單元格
-
@param firstRow
-
@param lastRow
-
@param firstCol
-
@param lastCol
-
@param sheet
*/
private static void genMergeCellByContent(int firstRow, int lastRow, int firstCol, int lastCol, HSSFSheet sheet) {class Range {
public String vlaue;
public int rowIndex;
public int firstCol;
public int lastCol;
}
String valueTemp = "";
int firstColTemp = 0;
int lastColTemp = 0;List
list = new ArrayList (); for (int i = firstRow; i <= lastRow; i++) {
Row row = sheet.getRow(i);
valueTemp = "";
for (int j = firstCol; j <= lastCol; j++) {
String stringCellValue = row.getCell(j).getStringCellValue();
if (valueTemp.equals(stringCellValue)) {
lastColTemp = j;
if (j == lastCol) {
Range range = new Range();
range.rowIndex = i;
range.vlaue = valueTemp;
range.firstCol = firstColTemp;
range.lastCol = lastColTemp;
list.add(range);
}
} else {
//找到合並單元信息。 存到list中
if (!valueTemp.equals("")) {
Range range = new Range();
range.rowIndex = i;
range.vlaue = valueTemp;
range.firstCol = firstColTemp;
range.lastCol = lastColTemp;
list.add(range);
}valueTemp = stringCellValue; firstColTemp = j; } }
}
for (Range range : list) {
sheet.addMergedRegion(new CellRangeAddress(range.rowIndex, range.rowIndex, range.firstCol, range.lastCol));
}
}
/**
-
合並單元格
-
@param split
*/
private static void genMergeHeader(String[] split, HSSFSheet sheet, int columnIndex, HSSFCellStyle style) {
for (int i = 0; i < split.length; i++) {HSSFRow row = null; row = sheet.getRow(i); if (row == null) { row = sheet.createRow(i); } HSSFCell cell = row.createCell(columnIndex); String s = split[i]; cell.setCellValue(s); HSSFFont font = sheet.getWorkbook().createFont(); style.setAlignment(HorizontalAlignment.CENTER); font.setFontName("宋體"); font.setFontHeightInPoints((short) 12);// 設置字體大小 font.setBold(true); style.setFont(font); style.setWrapText(true); style.setVerticalAlignment(VerticalAlignment.CENTER); cell.setCellStyle(style); sheet.setColumnWidth(columnIndex, s.length() * 700); // sheet.autoSizeColumn(columnIndex);
}
}
public static
void exportHeader(String excelName, List list, LinkedHashMap<String, Object> fieldMap) { // 設置默認文件名為當前時間:年月日時分秒 if (excelName == null || excelName == "") { excelName = new SimpleDateFormat("yyyyMMddhhmmss").format( new Date()).toString(); } try { //創建一個WorkBook,對應一個Excel文件 HSSFWorkbook wb = new HSSFWorkbook(); //在Workbook中,創建一個sheet,對應Excel中的工作薄(sheet) HSSFSheet sheet = wb.createSheet(excelName); //創建單元格,並設置值表頭 設置表頭居中 HSSFCellStyle style = wb.createCellStyle(); //創建一個居中格式 style.setAlignment(HorizontalAlignment.CENTER); // 填充工作表 fillSheet(sheet, list, fieldMap, style); //合並行 mergeRow(sheet, (List<HashMap>)list); FileOutputStream dd = new FileOutputStream("D://out//test.xls"); //將文件輸出 OutputStream ouputStream = dd; wb.write(ouputStream); ouputStream.flush(); ouputStream.close(); } catch (Exception e) { System.out.println(e.getMessage()); }
}
/**
-
合並行
-
@param sheet
-
@param list
*/
private static void mergeRow(HSSFSheet sheet,Listlist){
//獲取待合並單元格下標
List<MergeRowBuilder.ItemLink> genindexList = new MergeRowBuilder().BuidIndex(list);
//遍歷集合進行合並,每個相鄰單元格的信息都存儲在一個鏈表里
for (MergeRowBuilder.ItemLink itemList : genindexList) {
for (MergeRowBuilder.Item o : itemList.listItem) {
Integer[] tempArr = new Integer[2];
MergeRowBuilder.getIndex(o, tempArr);//獲取要和並的起始行和最后一行的下標
CellRangeAddress cellRangeAddress = new CellRangeAddress(tempArr[0]+4, tempArr[1]+4, o.getY(), o.getY());
sheet.addMergedRegionUnsafe(cellRangeAddress);}
}
}
public static void main(String[] args) {
LinkedHashMap<String, Object> headerHashMap = new LinkedHashMap<String, Object>(); LinkedHashMap<String, Object> hashMapSecond = new LinkedHashMap<String, Object>(); LinkedHashMap<String, Object> hashMapThird = new LinkedHashMap<String, Object>(); LinkedHashMap<String, Object> hashMapLeaf = new LinkedHashMap<String, Object>(); headerHashMap.put("序號", "序號"); headerHashMap.put("單位名稱", "單位名稱"); headerHashMap.put("單位類別", "單位類別"); headerHashMap.put("指標評分", "指標評分"); headerHashMap.put("百分制得分", "百分制得分"); headerHashMap.put("信息系統名稱", "信息系統名稱"); hashMapLeaf.put("防火(4)", ""); hashMapLeaf.put("問題", ""); hashMapLeaf.put("防雷(4)", "防火(4)"); hashMapLeaf.put("問題", ""); hashMapLeaf.put("場地(4)", "防火(4)"); hashMapLeaf.put("問題", ""); hashMapLeaf.put("濾空(4)", "防火(4)"); hashMapLeaf.put("問題", ""); hashMapLeaf.put("訪問控制(4)", "防火(4)"); hashMapLeaf.put("問題", ""); hashMapThird.put("機房綜合安全(20)", hashMapLeaf); hashMapSecond.put("信息安全建設(40)", hashMapThird); headerHashMap.put("檢查評分細項", hashMapSecond); LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>(); fieldMap.put("a", "序號"); fieldMap.put("b", "單位名稱"); fieldMap.put("c", "單位類別"); fieldMap.put("d", "指標評分"); fieldMap.put("e", "百分制得分"); fieldMap.put("f", "信息系統名稱"); fieldMap.put("g6", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-防火(4)"); fieldMap.put("g7", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-問題"); fieldMap.put("g8", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-防雷(4)"); fieldMap.put("g9", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-問題"); fieldMap.put("g10", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-場地(4)"); fieldMap.put("g11", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-問題"); fieldMap.put("g12", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-濾空(4)"); fieldMap.put("g13", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-問題"); fieldMap.put("g14", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-訪問控制(4)"); fieldMap.put("g15", "檢查評分細項-信息安全建設(40)-機房綜合安全(20)-問題"); fieldMap.put("g16", "檢查評分細項-信息安全建設(40)-基礎架構設施(15)-硬件設施(5)"); fieldMap.put("g17", "檢查評分細項-信息安全建設(40)-基礎架構設施(15)-問題"); fieldMap.put("g18", "檢查評分細項-信息安全建設(40)-基礎架構設施(15)-網絡架構(5)"); fieldMap.put("g19", "檢查評分細項-信息安全建設(40)-基礎架構設施(15)-問題"); fieldMap.put("g20", "檢查評分細項-信息安全建設(40)-基礎架構設施(15)-安全保障(5)"); fieldMap.put("g21", "檢查評分細項-信息安全建設(40)-基礎架構設施(15)-問題"); fieldMap.put("g22", "檢查評分細項-信息安全管理(20)-組織與工作(10)-信息安全主管領導(5)"); fieldMap.put("g23", "檢查評分細項-信息安全管理(20)-組織與工作(10)-問題"); fieldMap.put("g24", "檢查評分細項-信息安全管理(20)-組織與工作(10)-信息安全員(5)"); fieldMap.put("g25", "檢查評分細項-信息安全管理(20)-組織與工作(10)-問題"); fieldMap.put("g26", "檢查評分細項-信息安全管理(20)-安全與制度(10)-信息安全制度管理(5)"); fieldMap.put("g27", "檢查評分細項-信息安全管理(20)-安全與制度(10)-問題"); fieldMap.put("g28", "檢查評分細項-信息安全管理(20)-安全與制度(10)-崗位信息安全責任制度(5)"); fieldMap.put("g29", "檢查評分細項-信息安全管理(20)-安全與制度(10)-問題"); fieldMap.put("g30", "檢查評分細項-信息安全防護(40)-安全保護管理(15)-漏洞評測(15)"); fieldMap.put("g31", "檢查評分細項-信息安全防護(40)-安全保護管理(15)-問題"); fieldMap.put("g32", "檢查評分細項-信息安全防護(40)-信息安全應急(8)-信息安全應急預案(4)"); fieldMap.put("g33", "檢查評分細項-信息安全防護(40)-信息安全應急(8)-問題"); fieldMap.put("g34", "檢查評分細項-信息安全防護(40)-信息安全應急(8)-信息安全應急演練(4)"); fieldMap.put("g35", "檢查評分細項-信息安全防護(40)-信息安全應急(8)-問題"); fieldMap.put("g36", "檢查評分細項-信息安全防護(40)-Web應用系統(10)-身份驗證(3)"); fieldMap.put("g37", "檢查評分細項-信息安全防護(40)-Web應用系統(10)-問題"); fieldMap.put("g38", "檢查評分細項-信息安全防護(40)-Web應用系統(10)-上傳安全(3)"); fieldMap.put("g39", "檢查評分細項-信息安全防護(40)-Web應用系統(10)-問題"); fieldMap.put("g40", "檢查評分細項-信息安全防護(40)-Web應用系統(10)-抗拒絕服務(4)"); fieldMap.put("g41", "檢查評分細項-信息安全防護(40)-Web應用系統(10)-問題"); fieldMap.put("g42", "檢查評分細項-信息安全防護(40)-服務器操作系統(12)-Windows(6)"); fieldMap.put("g43", "檢查評分細項-信息安全防護(40)-服務器操作系統(12)-問題"); fieldMap.put("g44", "檢查評分細項-信息安全防護(40)-服務器操作系統(12)-Linux(6)"); fieldMap.put("g45", "檢查評分細項-信息安全防護(40)-服務器操作系統(12)-問題"); fieldMap.put("g46", "檢查評分細項-扣分指標- -安全事件(最多扣20分)"); fieldMap.put("g47", "檢查評分細項-扣分指標- -問題"); fieldMap.put("g48", "檢查評分細項-扣分指標- -媒體曝光(最多扣10分)"); fieldMap.put("g49", "檢查評分細項-扣分指標- -問題"); fieldMap.put("g50", "檢查評分細項-扣分指標- -材料報送效率(最多扣10分)"); fieldMap.put("g51", "檢查評分細項-扣分指標- -問題"); fieldMap.put("g52", "檢查評分細項-扣分指標- -開展信息安全等級保護工作(最多扣10分)"); fieldMap.put("g53", "檢查評分細項-扣分指標- -問題"); fieldMap.put("g54", " -加分指標- -等保建設"); fieldMap.put("g55", " -加分指標- -流量分析"); fieldMap.put("g56", " -加分指標- -日志分析"); List<HashMap> list = new ArrayList<HashMap>(); HashMap hm = new HashMap(); hm.put("a", "#1"); hm.put("b", "專"); hm.put("c", "低積載"); hm.put("d", "4"); hm.put("e", "5"); hm.put("f", "6"); hm.put("g", "7"); hm.put("g1", "8"); HashMap hm11 = new HashMap(); hm11.put("a", "#1"); hm11.put("b", "專"); hm11.put("c", "高積載"); hm11.put("d", "4"); hm11.put("e", "5"); hm11.put("f", "6"); hm11.put("g", "7"); hm11.put("g1", "8"); HashMap hm1 = new HashMap(); hm1.put("a", "#1"); hm1.put("b", "共同"); hm1.put("c", "32"); hm1.put("d", "43"); hm1.put("e", "54"); hm1.put("f", "65"); hm1.put("g", "74"); hm1.put("g1", "83"); HashMap hm2 = new HashMap(); hm2.put("a", "#2"); hm2.put("b", "專"); hm2.put("c", "322"); hm2.put("d", "43a"); hm2.put("e", "54a"); hm2.put("f", "65a"); hm2.put("g", "74a"); hm2.put("g1", "83a"); HashMap hm3 = new HashMap(); hm3.put("a", "#2"); hm3.put("b", "共同"); hm3.put("c", "322"); hm3.put("d", "43a"); hm3.put("e", "54a"); hm3.put("f", "65a"); hm3.put("g", "74a"); hm3.put("g1", "83a"); HashMap hm4 = new HashMap(); hm4.put("a", "5"); hm4.put("b", "5"); hm4.put("c", "322"); hm4.put("d", "43a"); hm4.put("e", "54a"); hm4.put("f", "65a"); hm4.put("g", "74a"); hm4.put("g1", "83a"); list.add(hm); list.add(hm11); list.add(hm1); list.add(hm2); list.add(hm3); list.add(hm4); exportHeader("test", list, fieldMap);
}
-
}