package com.artfess.poi.util; import cn.hutool.json.JSONUtil; import com.artfess.poi.Excel; import com.artfess.poi.HeaderNode; import lombok.extern.slf4j.Slf4j; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.RegionUtil; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.List; /** * @Description: * @Auther: tsy * @Date: 2022/10/09/5:27 下午 */ @Slf4j public class CustomHeader { public static void export(List headerNodes, HttpServletResponse response, String fileName) throws IOException { Excel excel = new Excel(); excel.sheet().sheetName("年度成绩信息"); // 产生工作薄对象 HSSFWorkbook workbook = excel.getWorkBook(); HSSFSheet sheet = workbook.getSheet("年度成绩信息"); HSSFCellStyle headStyle = workbook.createCellStyle(); defaultHeadStyle(headStyle); //表头层级 int deep = headerNodes.stream().map(HeaderNode::getRow).reduce(Integer::max).orElse(1); for (int i = 0; i <= 3; i++) { sheet.createRow(i); } for (HeaderNode headerNode : headerNodes) { int row = headerNode.getRow(); if(row <= 3) { int col = headerNode.getColumn(); excel.cell(headerNode.getRow(), headerNode.getColumn()).value(headerNode.getHeaderName()).style(headStyle); CellRangeAddress region; //是否跨列 if (headerNode.isOverNode()) { region = new CellRangeAddress(row, 3, col, col); } else { region = new CellRangeAddress(row, row, col, (col + headerNode.getOverNodeCount() - 1)); } if (region.getNumberOfCells() > 1) { sheet.addMergedRegionUnsafe(region); //合并后设置下边框 RegionUtil.setBorderTop(BorderStyle.THIN, region, sheet); RegionUtil.setBorderLeft(BorderStyle.THIN, region, sheet); RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet); RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet); } }else { excel.cell(headerNode.getRow(), headerNode.getColumn()).value(headerNode.getHeaderName()); } } ExcelUtil.downloadExcel(workbook, fileName, response); } public static void main(String[] args) { String customizeLabel = "[{\"headerName\":\"机构名称\",\"column\":0,\"row\":0},{\"headerName\":\"卡类型代码\",\"column\":1,\"row\":0},{\"headerName\":\"卡类型名称\",\"column\":2,\"row\":0},{\"headerName\":\"期初库存量\",\"column\":3,\"row\":0},{\"headerName\":\"本期入库情况\",\"column\":4,\"row\":0,\"overNodeCount\":4,\"overNode\":false},{\"headerName\":\"本期入库小计\",\"column\":4,\"row\":1},{\"headerName\":\"本期入库明细\",\"column\":5,\"row\":\"1\",\"overNodeCount\":3,\"overNode\":false},{\"headerName\":\"印刷入库\",\"column\":5,\"row\":2},{\"headerName\":\"领用入库\",\"column\":6,\"row\":2},{\"headerName\":\"回收入库\",\"column\":7,\"row\":2},{\"headerName\":\"本期出库情况\",\"column\":8,\"row\":0,\"overNodeCount\":7,\"overNode\":false},{\"headerName\":\"本期出库小计\",\"column\":8,\"row\":\"1\"},{\"headerName\":\"本期出库明细\",\"column\":9,\"row\":\"1\",\"overNodeCount\":6,\"overNode\":false},{\"headerName\":\"机构/部门下发出库\",\"column\":9,\"row\":2},{\"headerName\":\"员工下发出库\",\"column\":10,\"row\":2},{\"headerName\":\"回收提交出库\",\"column\":11,\"row\":2},{\"headerName\":\"清理出库\",\"column\":12,\"row\":2},{\"headerName\":\"销毁出库\",\"column\":13,\"row\":2},{\"headerName\":\"其他方式出库\",\"column\":14,\"row\":2},{\"headerName\":\"剩余库存量\",\"column\":15,\"row\":0}]"; List headerNodes = JSONUtil.toList(JSONUtil.parseArray(customizeLabel), HeaderNode.class); SXSSFWorkbook book = new SXSSFWorkbook(); SXSSFSheet sxssfSheet = book.createSheet("测试"); CellStyle headStyle = book.createCellStyle(); defaultHeadStyle(headStyle); //表头层级 int deep = headerNodes.stream().map(HeaderNode::getRow).reduce(Integer::max).orElse(1); for (int i = 0; i < deep; i++) { sxssfSheet.createRow(i); } //创建单元格 for (HeaderNode headerNode : headerNodes) { int row = headerNode.getRow(); int col = headerNode.getColumn(); SXSSFCell sxssfCell = sxssfSheet.getRow(row).createCell(col); sxssfSheet.setColumnWidth(col, headerNode.getWidth() * 256); sxssfCell.setCellStyle(headStyle); sxssfCell.setCellValue(headerNode.getHeaderName()); CellRangeAddress region; //是否跨列 if (headerNode.isOverNode()) { region = new CellRangeAddress(row, deep, col, col); } else { region = new CellRangeAddress(row, row, col, (col + headerNode.getOverNodeCount() - 1)); } if (region.getNumberOfCells() > 1) { sxssfSheet.addMergedRegionUnsafe(region); //合并后设置下边框 RegionUtil.setBorderTop(BorderStyle.THIN, region, sxssfSheet); RegionUtil.setBorderLeft(BorderStyle.THIN, region, sxssfSheet); RegionUtil.setBorderBottom(BorderStyle.THIN, region, sxssfSheet); RegionUtil.setBorderRight(BorderStyle.THIN, region, sxssfSheet); } } FileOutputStream fileOut = null; try { File file = new File("D:/excel/myExcel.xls"); fileOut = new FileOutputStream(file); book.write(fileOut); System.out.println("----Excle文件已生成------"); } catch (Exception e) { e.printStackTrace(); } finally { if (fileOut != null) { try { fileOut.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 表头样式 * * @param headStyle */ private static void defaultHeadStyle(CellStyle headStyle) { headStyle.setBorderTop(BorderStyle.THIN); headStyle.setBorderLeft(BorderStyle.THIN); headStyle.setBorderBottom(BorderStyle.THIN); headStyle.setBorderRight(BorderStyle.THIN); headStyle.setAlignment(HorizontalAlignment.CENTER); headStyle.setVerticalAlignment(VerticalAlignment.CENTER); headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); headStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); } }