POI导出excel,按照父子节点进行分级显示
public class ExcelExportUtil {
public static void exportManySheetExcel(String file, List<ExcelExp> mysheets) {
HSSFWorkbook wb = new HSSFWorkbook();// 创建工作薄
List<ExcelExp> sheets = mysheets;
// 表头样式
HSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
// 字体样式
HSSFFont fontStyle = wb.createFont();
fontStyle.setFontName("微软雅黑");
fontStyle.setFontHeightInPoints((short) 12);
fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
style.setFont(fontStyle);
for (ExcelExp excel : sheets) {
// 新建一个sheet
HSSFSheet sheet = wb.createSheet(excel.getFileName());// 获取该sheet名称
String[] handers = excel.getHanders();// 获取sheet的标题名
HSSFRow rowFirst = sheet.createRow(0);// 第一个sheet的第一行为标题
// 写标题
for (short i = 0; i < handers.length; i++) {
// 获取第一行的每个单元格
HSSFCell cell = rowFirst.createCell(i);
// 往单元格里写数据
cell.setCellValue(handers[i]);
cell.setCellStyle(style); // 加样式
sheet.setColumnWidth(i, (short) 6000); // 设置每列的列宽
}
// 写数据集
List<String[]> dataset = excel.getDataset();
maxJs = 0;
for (int i = 0; i < dataset.size(); i++) {
String[] data = dataset.get(i);// 获取该对象
// 创建数据行
HSSFRow row = sheet.createRow(i + 1);
for (short j = 0; j < data.length; j++) {
// 设置对应单元格的值
row.createCell(j).setCellValue(data[j]);
}
if (StringUtils.isNotEmpty(data[2])) {
getMaxJs(Integer.valueOf(data[2]));
}
}
if (maxJs > 0) {
groupNonDetailLevel(dataset, sheet);
}
}
// 写文件
try {
FileOutputStream out = new FileOutputStream(new File(file));
out.flush();
wb.write(out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
static int maxJs = 0;
/**
*
* @Description: 获取最大级数
* @author fhy
* @date 2022年6月22日
*/
public static int getMaxJs(int dwJs) {
if (dwJs > maxJs) {
maxJs = dwJs;
}
return maxJs;
}
/**
*
* @Description: 按照级数从大到小遍历
* @author fhy
* @date 2022年6月22日
*/
public static void groupNonDetailLevel(List<String[]> dataset,HSSFSheet sheet) {
for (int j = maxJs; j > 1; j--) {
groupDetailLevel(dataset,sheet,j);
}
}
/**
*
* @Description: 明细级分级展示。先折叠叶子节点,折叠后将dataset中的值替换为null
* (去掉当前的叶子节点,则上级成为了叶子节点,折叠上级;以此类推全部折叠)
* @author fhy
* @date 2022年6月22日
*/
public static void groupDetailLevel(List<String[]> dataset, HSSFSheet sheet,int level) {
String dwJs = "";
int startRow, endRow;
List<Integer> fromRowToRow = new ArrayList<Integer>();
for (int i = 0; i < dataset.size(); i++) {
String[] data = dataset.get(i);// 获取该对象
if (null == data) {
continue;
}
dwJs = data[2];
if (level == Integer.valueOf(dwJs)) {
//获取到叶子节点所在下标,放入list
fromRowToRow.add(i);
//置空
dataset.set(i, null);
} else {
if (CollectionUtils.isNotEmpty(fromRowToRow)) {
//从list中取出第一个和最后一个叶子节点的下标作为开始分组和结束分组的下标
startRow = fromRowToRow.get(0);
endRow = fromRowToRow.get(fromRowToRow.size() - 1);
sheet.groupRow(startRow + 1, endRow + 1);//分组
sheet.setRowGroupCollapsed(startRow + 1, true);//折叠
fromRowToRow.clear();
}
}
}
if (CollectionUtils.isNotEmpty(fromRowToRow)) {
startRow = fromRowToRow.get(0);
endRow = fromRowToRow.get(fromRowToRow.size() - 1);
sheet.groupRow(startRow + 1, endRow + 1);
sheet.setRowGroupCollapsed(startRow + 1, true);
fromRowToRow.clear();
}
}
}