使用EasyExcel合并单元格导出并使导出内容居中。

1、依赖

这里使用的是3.1.1版本的EasyExcel

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

2、需要导出的实体类对象

在实体类对象中使用注解@ExcelProperty,其中index表示最终导出时在第一行作为表头的顺序,value表示表头的名称。

@Data
@TableName(value = "company_info")
public class CompanyInfo {
    @ExcelProperty(index = 2,value = "企业Id")
    @TableField(value = "company_id")
    private int companyId;

    @ExcelProperty(index = 3,value = "企业名称")
    @TableField(value = "company_name")
    private String companyName;

    @ExcelProperty(index = 0,value = "股东Id")
    @TableField(value = "investor_id")
    private int investorId;

    @ExcelProperty(index = 1,value = "股东名称")
    @TableField(value = "investor_name")
    private String investorName;
}

3、合并单元格的工具类

/**
 * 合并单元格工具类
 *
 */
public class SimpleExcelMergeUtil implements CellWriteHandler {
    private int mergeStartRowIndex;
    private int[] mergeColumns;
    private List<Integer> mergeColumnList;
    public SimpleExcelMergeUtil() {
    }
    public SimpleExcelMergeUtil(int mergeStartRowIndex, int[] mergeColumns) {
        this.mergeStartRowIndex = mergeStartRowIndex;
        this.mergeColumns = mergeColumns;
        mergeColumnList = new ArrayList<>();
        for (int i : mergeColumns) {
            mergeColumnList.add(i);
        }
    }
    /**
     * 创建每个单元格之前执行
     *
     * @param writeSheetHolder
     * @param writeTableHolder
     * @param row
     * @param head
     * @param columnIndex
     * @param relativeRowIndex
     * @param isHead
     */
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
    }
    /**
     * 创建每个单元格之后执行
     *
     * @param writeSheetHolder
     * @param writeTableHolder
     * @param cell
     * @param head
     * @param relativeRowIndex
     * @param isHead
     */
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    }
    /**
     * 每个单元格数据内容渲染之后执行
     *
     * @param writeSheetHolder
     * @param writeTableHolder
     * @param cellData
     * @param cell
     * @param head
     * @param relativeRowIndex
     * @param isHead
     */

    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    }
    /**
     * 每个单元格完全创建完之后执行
     *
     * @param writeSheetHolder
     * @param writeTableHolder
     * @param cellDataList
     * @param cell
     * @param head
     * @param relativeRowIndex
     * @param isHead
     */

    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // 当前行
        int curRowIndex = cell.getRowIndex();
        // 当前列
        int curColIndex = cell.getColumnIndex();
        if (!isHead) {
            if (curRowIndex > mergeStartRowIndex && mergeColumnList.contains(curColIndex)) {
                // 从第二行数据行开始,获取当前行第二列数据
                Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
                // 获取上一行第二列数据
                Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
                Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
                if (curData.equals(preData)) {
                    Sheet sheet = writeSheetHolder.getSheet();
                    List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
                    boolean isMerged = false;
                    for (int i = 0; i < mergedRegions.size() && !isMerged; i++) {
                        CellRangeAddress cellRangeAddr = mergedRegions.get(i);
                        // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                        if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                            sheet.removeMergedRegion(i);
                            cellRangeAddr.setLastRow(curRowIndex);
                            sheet.addMergedRegion(cellRangeAddr);
                            isMerged = true;
                        }
                    }
                    // 若上一个单元格未被合并,则新增合并单元
                    if (!isMerged) {
                        CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
                        sheet.addMergedRegion(cellRangeAddress);
                    }
                }
            }
        }
    }
}

4、代码实现

/**
 * 合并单元格导出excel
 */
@PostMapping ("/exportMergeOneLine")
@ApiOperation(value = "导出excel(合并单元格)", notes = "导出excel导出excel(合并单元格)")
public void exportMergeOneLine() {
       QueryWrapper<CompanyInfo> queryWrapper = new QueryWrapper<>();
       queryWrapper.eq("investor_id", 3);
       List<CompanyInfo> companyInfos = companyInfoMapper.selectList(queryWrapper);
       log.info("companyInfos:{}", companyInfos);
       // 从第几行开始合并
       int mergeStartRowIndex = 1;
       // 需要合并哪些列
       int[] mergeColumns = {0,1};
       HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
       String fileName = "C:\\Users\\a\\Desktop\\(单列合并)用户信息表.xlsx";
       EasyExcel.write(fileName, CompanyInfo.class)
               .registerWriteHandler(new SimpleExcelMergeUtil(mergeStartRowIndex,mergeColumns))
               .registerWriteHandler(horizontalCellStyleStrategy)
               .autoCloseStream(true)
               .sheet("sheet名称")
               .doWrite(companyInfos);
}

5、测试数据

理想得出数据(investor_id :3,investor_name:云赛智联能够进行单元格合并)

效果:

6、为保证导出的内容都在单元格中居中显示需要添加EasyExcel 样式工具类:

/**
 * EasyExcel 样式工具类
 */
public class StyleUtils {
    /**
     * 标题样式
     * @return
     */
    public static WriteCellStyle getHeadStyle(){
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
//        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE1.getIndex());
//        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("宋体");//设置字体名字
        headWriteFont.setFontHeightInPoints((short)14);//设置字体大小
        headWriteFont.setBold(true);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;

        // 样式
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;

        headWriteCellStyle.setWrapped(true);  //设置自动换行;

        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return headWriteCellStyle;
    }


    /**
     * 内容样式
     * @return
     */
    public static WriteCellStyle getContentStyle(){
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

        // 背景绿色
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 设置字体
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontHeightInPoints((short) 12);//设置字体大小
        contentWriteFont.setFontName("宋体"); //设置字体名字
        contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;

        //设置样式;
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;

        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
        contentWriteCellStyle.setWrapped(true); //设置自动换行;

//        contentWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return contentWriteCellStyle;
    }
}

你可以使用 EasyExcel 库来导出合并单元格Excel 文件。下面是一个使用 EasyExcel 导出合并单元格的示例代码: ```java // 导入所需的包 import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; public class ExcelExportDemo { public static void main(String[] args) { // 设置导出文件路径 String filePath = "path/to/exported/file.xlsx"; // 创建数据列表 List<List<Object>> data = new ArrayList<>(); // 添加数据 List<Object> rowData = new ArrayList<>(); rowData.add("A1"); rowData.add("B1"); rowData.add("C1"); data.add(rowData); // 创建合并策略,设置需要合并的单元格范围 LoopMergeStrategy mergeStrategy = new LoopMergeStrategy(0, 0); // 导出 Excel 文件 EasyExcel.write(filePath) .registerWriteHandler(mergeStrategy) .sheet("Sheet1") .doWrite(data); System.out.println("Excel exported successfully!"); } } ``` 上述代码中,我们首先导入了 EasyExcel 相关的包。然后,我们定义了一个 `ExcelExportDemo` 类,并在 `main` 方法中编写导出 Excel 文件的代码。 在这个示例中,我们创建了一个包含一行三列数据的列表,然后使用 `LoopMergeStrategy` 设置了需要合并的单元格范围为第一行的所有列。最后,我们调用 `EasyExcel.write` 方法来实际导出 Excel 文件,传入文件路径、合并策略和数据列表。 你可以根据需要进行修改和扩展,以满足具体的导出需求。希望以上信息对你有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值