使用easyexcel动态生成excel导出模版总结

1.简单模版动态导出

public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\easyexcel-export-user5.xlsx"));
        List<List<String>> headColumnMap = new ArrayList<>();
         //主体
        String title = "能源";
        headColumnMap.add(Lists.newArrayList(title, "设备编号"));
        headColumnMap.add(Lists.newArrayList(title, "关联表计"));
        headColumnMap.add(Lists.newArrayList(title, "投用日期"));
        headColumnMap.add(Lists.newArrayList(title, "备注"));
        headColumnMap.add(Lists.newArrayList(title, "是否启用"));
        //内容 需要一一对应
        List<List<Object>> dataList = new ArrayList<>();
        dataList.add(Lists.newArrayList("对应标号","未关联","2020-01-01","无备注","禁用"));

        byte[] excelFile = createExcelFile(headColumnMap, dataList, null, "cs");
//        byte[] excelFile = createWithSumExcelFile(headColumnMap, dataList, null, "cs", dataList.size(),1);
        fileOutputStream.write(excelFile);
        fileOutputStream.close();

    }

注意:数据要和标题进行对应

根据该工具类可以快速生成此类简单的excel导出数据模版

2.导出 动态生成多层级excel

思路,该excel数据不同点在于层级名称

有多少层级,就展示多少层级,那么获取该数据最后一层级就可以算出需要导出多少层(可以通过FSD)等树的遍历获取最大深度

不同层级的数据存放位置不相同,其余为需要设置null占位

工具类主体


/**
 * DynamicEasyExcelExportUtils 动态表格工具
 *
 * @author Xujie
 * @version 2024/08/09 08:58
 **/
public class DynamicEasyExcelExportUtils {

    private static final Logger log = LoggerFactory.getLogger(DynamicEasyExcelExportUtils.class);

    private static final String DEFAULT_SHEET_NAME = "sheet1";


    /**
     * 生成不需要合计的excel文件
     *
     * @param excelHead     表头
     * @param excelRows      数据
     * @param mergeColumnNames 需要合并的列
     * @param sheetName       sheet名称
     * @return
     */
    public static byte[] createExcelFile(List<List<String>> excelHead, List<List<Object>> excelRows, List<String> mergeColumnNames, String sheetName) {
        try {
            if (CollectionUtils.isNotEmpty(excelHead)) {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                EasyExcel.write(outputStream).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .head(excelHead)
                        .registerWriteHandler(new CustomMergeStrategy(mergeColumnNames))
                        .registerWriteHandler(new AdaptiveColumnWidthStrategy())
                        .registerWriteHandler(getHorizontalCellStyleStrategy())
                        .sheet(sheetName)
                        .doWrite(excelRows);
                return outputStream.toByteArray();
            }
        } catch (Exception e) {
            log.error("动态生成excel文件失败,headColumns:" + JSONArray.toJSONString(excelHead) + ",excelRows:" + JSONArray.toJSONString(excelRows), e);
        }
        return null;
    }

    /**
     * 生成需要合计的excel文件
     *
     * @param excelHead       表头
     * @param excelRows      数据
     * @param mergeColumnNames 需要合并的列
     * @param sheetName      sheet名称
     * @param rowIndex         第几行是合计
     * @param colMergeLength   合计后需要合并多少列不包括合计那一列
     */
    public static byte[] createWithSumExcelFile(List<List<String>> excelHead, List<List<Object>> excelRows, List<String> mergeColumnNames, String sheetName, int rowIndex, int colMergeLength) {
        try {
            if (CollectionUtils.isNotEmpty(excelHead)) {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                EasyExcel.write(outputStream).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .head(excelHead)
                        .registerWriteHandler(new CustomMergeStrategy(mergeColumnNames))
                        .registerWriteHandler(new AdaptiveColumnWidthStrategy())
                        .registerWriteHandler(new ColMergeStrategy(true, rowIndex, colMergeLength))
                        .registerWriteHandler(getHorizontalCellStyleStrategy())
                        .sheet(sheetName)
                        .doWrite(excelRows);
                return outputStream.toByteArray();
            }
        } catch (Exception e) {
            log.error("动态生成excel文件失败,headColumns:{},excelRows:{}", JSONArray.toJSONString(excelHead), JSONArray.toJSONString(excelRows), e);
        }
        return null;
    }

    /**
     * 导出样式居中
     *
     * @author Xujie
     * @date 2024/8/12 上午11:33
     */
    public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 设置背景颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        // 设置头字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 13);
        headWriteFont.setBold(true);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 设置头居中
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 内容策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 设置 水平居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 设置垂直居中
        contentWriteCellStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 11);
        contentWriteFont.setFontName("宋体");
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    /**
     * 导出文件测试
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\easyexcel-export-user5.xlsx"));
        List<List<String>> headColumnMap = new ArrayList<>();
        headColumnMap.add(Lists.newArrayList("支路编号"));
        headColumnMap.add(Lists.newArrayList("支路名称"));
        headColumnMap.add(Lists.newArrayList("00:00"));
        headColumnMap.add(Lists.newArrayList("00:10"));
        headColumnMap.add(Lists.newArrayList("总计"));
        List<List<Object>> dataList = new ArrayList<>();
        dataList.add(Lists.newArrayList("1", "支路1", "100", "100", "1000"));
        dataList.add(Lists.newArrayList("2", "支路2", "200", "2000", "2000"));
        byte[] excelFile = createExcelFile(headColumnMap, dataList, null, "cs");
        fileOutputStream.write(excelFile);
        fileOutputStream.close();

    }

}

合并策略类 

/**
 * CustomMergeStrategy excel到处单元格相同合并策略
 *
 * @author Xujie
 * @version 2024/08/09 09:06
 **/
public class CustomMergeStrategy implements CellWriteHandler {

    private List<String> mergeColumnNames = null;


    public CustomMergeStrategy(List<String> mergeColumnNames) {
        this.mergeColumnNames = mergeColumnNames;
    }

    public CustomMergeStrategy() {
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // 检验:是否表头
        if (isHead) {
            return;
        }
//         检验:是否第一行
        if (relativeRowIndex == 1) {
            return;
        }
        // 检验:是否设置合并列策略
        if (mergeColumnNames == null) {
            return;
        }
        String headName = head.getHeadNameList().get(0);

        if (!mergeColumnNames.contains(headName)) {
            return;
        }
        // 获取当前行数据
        Sheet sheet = cell.getSheet();
        int rowIndexCurrent = cell.getRowIndex();
        int rowIndexPrev = rowIndexCurrent - 1;

        Row rowCurrent = sheet.getRow(rowIndexCurrent);
        Row rowPrev = sheet.getRow(rowIndexPrev);
        if (rowPrev == null) {
            return;
        }
        Cell cellPrev = rowPrev.getCell(cell.getColumnIndex());

        // 获取当前当前单元和上一单元数据 默认字符串
        String cellValueCurrent = cell.getStringCellValue();
        String cellValuePrev = cellPrev.getStringCellValue();

        //是否相等
        if (!cellValueCurrent.equals(cellValuePrev)) {
            return;
        }

        //合并
        Boolean isMerged = false;
        //获取以及合并的区域
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
        for (int i = 0; i < mergedRegions.size(); i++) {
            CellRangeAddress cellRangeAddress = mergedRegions.get(i);
            if (cellRangeAddress.isInRange(rowIndexPrev, cell.getColumnIndex())) {
                //删除之前的
                sheet.removeMergedRegion(i);
                // 合并单元格
                cellRangeAddress.setLastRow(cell.getRowIndex());
                sheet.addMergedRegion(cellRangeAddress);
                isMerged = true;
                break;
            }
        }
        if (!isMerged) {
            // 合并单元格
            sheet.addMergedRegion(new CellRangeAddress(rowIndexPrev, rowIndexCurrent, cell.getColumnIndex(), cell.getColumnIndex()));
        }


    }
}

表头格式设置

/**
 * AdaptiveColumnWidthStrategy 表头自适应列宽
 *
 * @author Xujie
 * @version 2024/08/12 10:38
 **/
public class AdaptiveColumnWidthStrategy extends AbstractColumnWidthStyleStrategy {

    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        //表头自适应列宽
        if (isHead) {
            int length = cell.getStringCellValue().getBytes().length;
            if (length < 5) {
                length = 5;
            }
            writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), length * 400);
        }
    }
}

 

可以使用 EasyExcel 结合 Ajax 实现模板导出 Excel 的功能,具体步骤如下: 1. 在前端页面中使用 Ajax 向后端发送请求,请求获取 Excel 数据; 2. 后端根据请求参数生成 Excel 数据,并利用 EasyExcel 将数据写入 Excel 模板; 3. 后端将生成Excel 文件流返回给前端; 4. 前端利用 Blob 对象创建文件流,并使用 FileSaver.js 将文件保存至本地。 以下是一个简单的示例代码: 前端代码: ```javascript function exportExcel() { $.ajax({ url: '/excel/export', type: 'POST', dataType: 'json', success: function(res) { var blob = new Blob([res], { type: 'application/vnd.ms-excel' }); saveAs(blob, 'example.xlsx'); }, }); } ``` 后端代码: ```java @PostMapping("/excel/export") public void exportExcel(HttpServletResponse response) throws IOException { // 获取 Excel 数据并填充至模板中 List<ExcelData> dataList = getDataList(); InputStream inputStream = getClass().getResourceAsStream("/templates/example.xlsx"); OutputStream outputStream = response.getOutputStream(); EasyExcel.write(outputStream).withTemplate(inputStream).sheet().doFill(dataList); // 设置响应头 response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=example.xlsx"); response.flushBuffer(); } ``` 其中,`getDataList()` 方法用于获取 Excel 数据,`example.xlsx` 是 Excel 模板文件。需要注意的是,EasyExcel 需要在后端项目中引入依赖,同时在前端页面中引入 FileSaver.js。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值