easyexcel 模板填充Excel数据,实现自定义换行及动态调整行高,并保持列表格式一致

news/2024/7/7 19:32:27 标签: excel

pom依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>

替换核心代码:

public static InputStream onlineWriter(String fileType, InputStream inputStream, JSONObject model) throws Exception {

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try (ExcelWriter excelWriter = EasyExcel.write(out).withTemplate(inputStream)
            .registerWriteHandler(new CustomCellWeightWeightConfig())
            .registerWriteHandler(new CustomMergeStrategy())
            .build()) {

        // 设置自动换行,前提内容中需要加「\n」才有效
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        writeCellStyle.setWrapped(true);

        HorizontalCellStyleStrategy cellStyleStrategy = new HorizontalCellStyleStrategy(null, writeCellStyle);
        WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(cellStyleStrategy).build();

        excelWriter.fill(model, writeSheet);

        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
        for (Map.Entry<String, Object> entry : model.entrySet()) {
            if (entry.getValue() instanceof ArrayList) {
                JSONArray jsonArray = JSON.parseArray(JSONObject.toJSONString(entry.getValue()));
                FillWrapper fillWrapper = new FillWrapper(entry.getKey(), jsonArray);
                excelWriter.fill(fillWrapper, fillConfig, writeSheet);
            }
        }
        excelWriter.finish();
    }
    return new ByteArrayInputStream(out.toByteArray());
}

自定义调整行高策略:

/**
 * 填充内容包含\n换行符,重新计算行高
 */
public class CustomCellWeightWeightConfig extends AbstractColumnWidthStyleStrategy {

    private Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();

    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

        boolean needSetWidth = isHead || StringUtils.isNotEmpty(cellDataList);
        if (needSetWidth) {
            //包含\n的内容修改行高
            String cellValue = getCellValue(cell);
            boolean contains =  StringUtils.contains(cellValue, ExcelTemplateUtil.WRAPPED);
            if (contains) {
                int rows = cellValue.split(ExcelTemplateUtil.WRAPPED).length;
                float height = cell.getRow().getHeightInPoints();
                cell.getRow().setHeightInPoints(rows * height);
            }
        }
    }

    public static String getCellValue(Cell cell) {
        String cellValue;
        switch (cell.getCellType()) {
            case STRING:
                cellValue = cell.getStringCellValue();
                break;
            case BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case NUMERIC:
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            default:
                cellValue = "";
                break;
        }
        return cellValue;
    }

}

自定义合并表格策略:


/**
 * 表格填充 每一列都赋值上一列的格式,确保列格式一致
 */
public class CustomMergeStrategy extends AbstractMergeStrategy {

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if(relativeRowIndex==null ||relativeRowIndex==0){
            return;
        }

        int rowIndex = cell.getRowIndex();
        int colIndex = cell.getColumnIndex();
        sheet=cell.getSheet();
        Row preRow = sheet.getRow(rowIndex - 1);
        Cell preCell = preRow.getCell(colIndex);//获取上一行的该格
        List<CellRangeAddress> list = sheet.getMergedRegions();
        for (int i = 0; i < list.size(); i++) {
            CellRangeAddress cellRangeAddress = list.get(i);
            if (cellRangeAddress.containsRow(preCell.getRowIndex()) && cellRangeAddress.containsColumn(preCell.getColumnIndex())) {
                int lastColIndex = cellRangeAddress.getLastColumn();
                int firstColIndex = cellRangeAddress.getFirstColumn();
                if (lastColIndex > firstColIndex) {

                    int lastRowIndex = cellRangeAddress.getLastRow();
                    CellRangeAddress cra = new CellRangeAddress(rowIndex, rowIndex, firstColIndex, lastColIndex);
                    sheet.addMergedRegion(cra);

                    //设置合并区域cra的边框
                    RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheet);
                    RegionUtil.setBorderLeft(BorderStyle.THIN, cra, sheet);
                    RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheet);
                    RegionUtil.setBorderTop(BorderStyle.THIN, cra, sheet);
                    return;
                }
            }
        }
    }

}

http://www.niftyadmin.cn/n/5535119.html

相关文章

【软件测试】之黑盒测试用例的设计

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1.测试用例的概念2.测试用例的好处3. 黑盒测试用例的设计3.1 黑盒测试的概念3.2 基于需求进行测…

LLDP 基本原理

LLDP 简介 定义 LLDP&#xff08;Link Layer Discovery Protocol&#xff0c;链路层发现协议&#xff09;是 IEEE 802.1ab 中定义的第二层发现&#xff08;Layer 2 Discovery&#xff09;协议。 LLDP 提供了一种标准的链路层发现方式&#xff0c;可以将本端设备的主要能力、…

力扣第217题“存在重复元素”

在本篇文章中&#xff0c;我们将详细解读力扣第217题“存在重复元素”。通过学习本篇文章&#xff0c;读者将掌握如何使用哈希表和排序方法来解决这一问题&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述 力…

电脑有线网卡和无线网卡的MAC地址

电脑上的无线网卡和有线网卡是两种不同类型的网络接口卡&#xff0c;它们各自有不同的功能和连接方式。 无线网卡&#xff1a; 功能&#xff1a;无线网卡允许计算机通过无线信号连接到网络&#xff0c;通常是Wi-Fi网络。连接方式&#xff1a;无需物理电缆&#xff0c;通过无线…

目标检测入门:3.目标检测损失函数(IOU、GIOU、GIOU)

目录 一、IOU 二、GIOU 三、DIOU 四、DIOU_Loss实战 在前面两章里面训练模型时&#xff0c;损失函数都是选择L1Loss&#xff08;平均绝对值误差&#xff08;MAE&#xff09;&#xff09;损失函数&#xff0c;L1Loss损失函数公式如下: 由公式可知&#xff0c;L1Loss损失函数…

架构 | 数据归档

INDEX 1 通用思路2 快速归档3 归档整体流程&#xff08;完整归档 & 快速归档&#xff09;4 准备阶段4.1 确认归档表4.2 思路&#xff1a;确认归档数据范围 & 归档方案待选&#xff08;重点&#xff09;4.3 归档方式选择 & 业务场景覆盖4.4 确认归档数据范围 & …

如何在操作使用ufw设置防火墙

UFW&#xff08;简单防火墙&#xff09;是用于管理iptables防火墙规则的用户友好型前端。它的主要目标是使iptables的管理更容易。 在学习Linux的时候大家一般都会关心命令&#xff0c;Posix API和桌面等&#xff0c;很少会去了解防护墙。其实除了一些网络安全厂商提供的付费防…

四、(3)补充beautifulsoup、re正则表达式、标签解析

四、&#xff08;3&#xff09;补充beautifulsoup、re正则表达式、标签解析 beautifulsoupre正则表达式正则提取标签解析 beautifulsoup 补充关于解析的知识 还需要看爬虫课件 如何定位文本或者标签&#xff0c;是整个爬虫中非常重要的能力 无论find_all&#xff08;&#xff…