实现效果如下

具体代码:
动态表头数据
public List<List<String>> buildHead() {
R<List<RentalProperty>> rentalPropertyR = smartPropertyClient.getRentalPropertyListByTenantId(AuthUtil.getTenantId());
List<String> feeProjectNameList = new ArrayList<>();
if (rentalPropertyR.isSuccess() && rentalPropertyR.getData().size() > 0) {
for (RentalProperty rentalProperty : rentalPropertyR.getData()) {
feeProjectNameList.add(rentalProperty.getName());
}
}
List<List<String>> head = new ArrayList<>();
String headFirst = "历史账单导入模版\n(统计起始时间:2018年5月 截止时间:填表月的上一个月)";
String headSecond = "填表须知:\n" +
"1.带*的为必填项,每个公司下的合同单独存一个文件\n" +
"2.此数据为示例,缴费周期:按月\n" +
"3.每个起始时间、终止时间为合同缴费周期的账单日期:如按季,则起始时间为2023/1/5 终止时间为历时月,以此类推。\n" +
"4.支持批量导入,直接在表格中将所有合同的账单内容填写完成即可\n" +
"5.请务必确认合同号及账单内容填写无误";
head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "*合同号", "*合同号"));
head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "所属楼盘", "所属楼盘"));
head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "房屋描述", "房屋描述"));
head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "*起始时间", "*起始时间"));
head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "*终止时间", "*终止时间"));
feeProjectNameList.stream()
.forEach(temp -> head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "*应收项目", temp)));
head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "*实收项目", "转账实收(元)"));
head.add(Lists.newArrayList(headFirst, headFirst, headSecond, "*未收租金(元)", "*未收租金(元)"));
return head;
}
下载方法
public static void download2(HttpServletResponse response, String fileName, List<List<String>> headList,
List data) throws IOException {
String excelName = StringUtil.isNotBlank(fileName) ? fileName : "" + DateUtil.format(new java.util.Date(), "yyyy-MM");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
excelName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + excelName + ".xlsx");
List<Integer> columnIndexes = IntStream.range(0, 4).boxed().collect(Collectors.toList());
CellStyleStrategy cellStyleStrategy = new CellStyleStrategy(columnIndexes, new WriteCellStyle(), new WriteCellStyle());
EasyExcel.write(response.getOutputStream())
.registerWriteHandler(getData2Style())
.registerWriteHandler(cellStyleStrategy)
.inMemory(true)
.registerWriteHandler(new WriteHandlerStrategy())
.registerWriteHandler(new CellRowHeightStyleStrategy())
.head(headList).excelType(ExcelTypeEnum.XLSX)
.sheet("sheet1")
.doWrite(data);
}
public static HorizontalCellStyleStrategy getData2Style() {
WriteCellStyle borderedCellStyle = new WriteCellStyle();
borderedCellStyle.setBorderTop(BorderStyle.THIN);
borderedCellStyle.setBorderBottom(BorderStyle.THIN);
borderedCellStyle.setBorderLeft(BorderStyle.THIN);
borderedCellStyle.setBorderRight(BorderStyle.THIN);
borderedCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
return new HorizontalCellStyleStrategy(borderedCellStyle, borderedCellStyle);
}
最主要的方法
public class CellStyleStrategy extends HorizontalCellStyleStrategy {
private final WriteCellStyle headWriteCellStyle;
private final WriteCellStyle contentWriteCellStyle;
private final List<Integer> columnIndexes;
public CellStyleStrategy(List<Integer> columnIndexes, WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
this.columnIndexes = columnIndexes;
this.headWriteCellStyle = headWriteCellStyle;
this.contentWriteCellStyle = contentWriteCellStyle;
}
@Override
protected void setHeadCellStyle(CellWriteHandlerContext context) {
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontName("宋体");
headWriteFont.setFontHeightInPoints((short) 11);
headWriteCellStyle.setBorderTop(BorderStyle.THIN);
headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
headWriteCellStyle.setBorderRight(BorderStyle.THIN);
headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headWriteFont.setBold(false);
headWriteCellStyle.setWriteFont(headWriteFont);
headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
if (context.getRowIndex() == 1 || (context.getRowIndex() >= 3 && context.getRowIndex() <= 4)) {
headWriteCellStyle.setWriteFont(headWriteFont);
headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
} else if (context.getRowIndex() == 2) {
headWriteCellStyle.setWriteFont(headWriteFont);
headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
}
if (stopProcessing(context)) {
return;
}
WriteCellData<?> cellData = context.getFirstCellData();
WriteCellStyle.merge(headWriteCellStyle, cellData.getOrCreateStyle());
}
设置*号为红色
public class WriteHandlerStrategy implements CellWriteHandler {
@Override
public void beforeCellCreate(final WriteSheetHolder writeSheetHolder, final WriteTableHolder writeTableHolder,
final Row row, final Head head, final Integer columnIndex,
final Integer relativeRowIndex, final Boolean isHead) {
}
@Override
public void afterCellCreate(final WriteSheetHolder writeSheetHolder, final WriteTableHolder writeTableHolder,
final Cell cell, final Head head, final Integer relativeRowIndex, final Boolean isHead) {
}
public void afterCellDispose(final WriteSheetHolder writeSheetHolder, final WriteTableHolder writeTableHolder,
final List<WriteCellData<?>> list, final Cell cell, final Head head, final Integer integer,
final Boolean aBoolean) {
if (cell.getStringCellValue().contains("*")) {
Sheet sheet = writeSheetHolder.getSheet();
Workbook workbook = sheet.getWorkbook();
XSSFRichTextString richString = new XSSFRichTextString(cell.getStringCellValue());
Font font = workbook.createFont();
font.setColor(Font.COLOR_RED);
richString.applyFont(0, 1, font);
cell.setCellValue(richString);
}
}
}
设置行高
public class CellRowHeightStyleStrategy extends AbstractRowHeightStyleStrategy {
@Override
protected void setContentColumnHeight(Row row, int relativeRowIndex) {
}
@Override
protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
if (relativeRowIndex == 2) {
row.setHeight((short) (3200));
}
}
}