[alibaba/easyexcel]复杂表头生成,求助

2023-04-26 96 views
0

求助如何生成如下的表头: image

尝试使用代码:

heads.add(Arrays.asList("报表逻辑: 展示时点情况,每日封存(以每天00:00为节点,今日修改后要24点后导出才能查看最新情况)"));
heads.add(Arrays.asList(""));
heads.add(Arrays.asList("基础信息", "平台公司"));
heads.add(Arrays.asList("基础信息", "项目名称"));

无法达到效果。求助 @clevertension @wenshao @smart-techs @wcc526 @alaahong 各位大佬看看

回答

3
heads.add(Arrays.asList("基础信息","aaa"));
heads.add(Arrays.asList("基础信息", "平台公司"));
heads.add(Arrays.asList("基础信息", "项目名称"));
heads.add(Arrays.asList("基础信息", "项目bb"));
6

至于你最上面那个 报表逻辑 跟表头没有关系

7

可以使用 poi的api xssfSheet.shiftRows(); 去移动整张表 在上面插入你想要的

2

可以使用 poi的api xssfSheet.shiftRows(); 去移动整张表 在上面插入你想要的

有具体的示例代码吗?我现在是先创建List头格式的sheet仅仅写入头,然后通过不写入头的方式,去写入数据。

EasyExcel.write(response.getOutputStream())
                .head(heads)
                // 不要自动关闭,交给 Servlet 自己处理
                .autoCloseStream(false)
                // 基于 column 长度,自动适配。最大 255 宽度
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet(sheetName)
                .doWrite(dataList);
4

可以使用 poi的api xssfSheet.shiftRows(); 去移动整张表 在上面插入你想要的

有具体的示例代码吗?我现在是先创建List头格式的sheet仅仅写入头,然后通过不写入头的方式,去写入数据。

EasyExcel.write(response.getOutputStream())
                .head(heads)
                // 不要自动关闭,交给 Servlet 自己处理
                .autoCloseStream(false)
                // 基于 column 长度,自动适配。最大 255 宽度
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet(sheetName)
                .doWrite(dataList);

自定义SheetWriteHandler执行,没有例子

8

可以使用 poi的api xssfSheet.shiftRows(); 去移动整张表 在上面插入你想要的

有具体的示例代码吗?我现在是先创建List头格式的sheet仅仅写入头,然后通过不写入头的方式,去写入数据。

EasyExcel.write(response.getOutputStream())
                .head(heads)
                // 不要自动关闭,交给 Servlet 自己处理
                .autoCloseStream(false)
                // 基于 column 长度,自动适配。最大 255 宽度
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet(sheetName)
                .doWrite(dataList);

自定义SheetWriteHandler执行,没有例子

使用自定义SheetWriteHandler,报错了

public class ProjectExportSheetWriteHandler implements SheetWriteHandler {

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        // 整体表格向下移动2格
        Sheet sheet = writeSheetHolder.getSheet();
        sheet.shiftRows(0, sheet.getLastRowNum(), 2);  // 这里报错了
        // 在第一行第一列插入固定数据
        Row row = sheet.getRow(0);
        if (row == null) {
            row = sheet.createRow(0);
        }
        Cell cell = row.createCell(0);
        cell.setCellValue("报表逻辑: 展示时点情况,每日封存(以每天00:00为节点,今日修改后要24点后导出才能查看最新情况)");
    }
}

报错信息: java.lang.RuntimeException: Not Implemented at org.apache.poi.xssf.streaming.SXSSFSheet.shiftRows(SXSSFSheet.java:967) at com.wk.dc.sys.util.ProjectExportSheetWriteHandler.afterSheetCreate(ProjectExportSheetWriteHandler.java:19) at com.alibaba.excel.write.handler.SheetWriteHandler.afterSheetCreate(SheetWriteHandler.java:37) at com.alibaba.excel.util.WriteHandlerUtils.afterSheetCreate(WriteHandlerUtils.java:114) at com.alibaba.excel.util.WriteHandlerUtils.afterSheetCreate(WriteHandlerUtils.java:102) at com.alibaba.excel.context.WriteContextImpl.initSheet(WriteContextImpl.java:195) at com.alibaba.excel.context.WriteContextImpl.currentSheet(WriteContextImpl.java:125) at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:54) at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:73) at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:50) at com.alibaba.excel.write.builder.ExcelWriterSheetBuilder.doWrite(ExcelWriterSheetBuilder.java:62)

4

你刚创建完sheet就移动不肯定报错吗? 肯定是数据处理完之后最后搞啊

6

你刚创建完sheet就移动不肯定报错吗? 肯定是数据处理完之后最后搞啊

翻阅源码,是因为ExcelWriter生成.xlsx的工作簿是SXSSFSheet类型的,而Poi中的SXSSFSheet不支持shiftRows。

@NotImplemented
    public void shiftRows(int startRow, int endRow, int n) {
        throw new RuntimeException("Not Implemented");
    }
0

数据量小的话可以setMemory 为true

2

数据量小的话可以setMemory 为true

已解决。自定义SheetWriteHandler,将固定数据写入sheet,然后写入数据时,跳过n行才写入表头和表数据。由于这里是动态头,所以使用了无对象的写入方式。可根据需要自行调整

@Slf4j
public class ProjectExportSheetWriteHandler implements SheetWriteHandler {

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        Sheet sheet = workbook.getSheetAt(0);
        //
        Row row1 = sheet.createRow(0);
        Cell cell = row1.createCell(0);
        cell.setCellValue("报表逻辑: 展示时点情况,每日封存(以每天00:00为节点,今日修改后要24点后导出才能查看最新情况)");
        cell.setCellStyle(buildRow1CellStyle(workbook));
        //
        Row row2 = sheet.createRow(1);
        Cell cell1 = row2.createCell(0);
        cell1.setCellValue("");
    }

    private CellStyle buildRow1CellStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setAlignment(HorizontalAlignment.LEFT);
        Font font = workbook.createFont();
        font.setBold(false);
        font.setColor(HSSFColor.HSSFColorPredefined.ORANGE.getIndex());
        cellStyle.setFont(font);

        return cellStyle;
    }
}

导出时

 public static <T> void writeWith(HttpServletResponse response, String filename, String sheetName,
                                 List<List<String>> head, List<T> data, WriteHandler... writeHandlers) throws IOException {
        // 设置 header 和 contentType
        setResponse(response, filename);

        // 输出 Excel
        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(response.getOutputStream())
                .head(head);
        for (WriteHandler writeHandler : writeHandlers) {
            excelWriterBuilder.registerWriteHandler(writeHandler);
        }
        // 不要自动关闭,交给 Servlet 自己处理
        excelWriterBuilder.autoCloseStream(false)
                .relativeHeadRowIndex(3) // 关键点
                .excelType(ExcelTypeEnum.XLS) // 关键点
                .sheet(sheetName)
                .doWrite(data);
    }