一、前言

最近在使用ruoyi框架,但是发现它自带的exportExcel功能不够方便,遂使用alibaba的easyExcel包。

首先我们先来看看ruoyi自带的exportExcel功能:

image-20230712151249323

我们可以看看导出结果:

image-20230712151332139

其实还是挺好看的是吧,但如果我们想添加合并单元格的功能就有点不方便了。

二、导入依赖

我们首先在ruoyi-common模块导入easyExcel的依赖包

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

三、修改实体类

ruoyi框架的实体类需要在导出的字段上添加@Excel注解:

public class SysPost extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC)
    private Long postId;

    @Excel(name = "岗位编码")
    private String postCode;

    @Excel(name = "岗位名称")
    private String postName;

    @Excel(name = "岗位排序", cellType = ColumnType.NUMERIC)
    private String postSort;

    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;

    private boolean flag = false;
    
    // TODO
}

但是easyExcel需要把注解改为@ExcelProperty,并在类上添加@ExcelIgnoreUnannotated注解,该注解的功能是导出时忽略未加注解的属性。

我们也可以添加一些样式的注解,让导出格式更好看。

@ExcelIgnoreUnannotated
// 字体水平垂直居中
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER,
                verticalAlignment = VerticalAlignmentEnum.CENTER)
public class SysPost extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    @ExcelProperty("岗位序号")
    @HeadFontStyle(fontHeightInPoints = 11)// 设置标题字体
    private Long postId;

    @ExcelProperty("岗位编码")
    @HeadFontStyle(fontHeightInPoints = 11)
    private String postCode;

    @ExcelProperty("岗位名称")
    @HeadFontStyle(fontHeightInPoints = 11)
    private String postName;

    @ExcelProperty("岗位排序")
    @HeadFontStyle(fontHeightInPoints = 11)
    private String postSort;

    @ExcelProperty("状态")
    @HeadFontStyle(fontHeightInPoints = 11)
    private String status;

    private boolean flag = false;
    
    // TODO
}

四、修改ExcelUtil类

ExcelUtil.java新增easyexcel导出方法:

/**
 * 对list数据源将其里面的数据导入到excel表单(EasyExcel)
 * 
 * @param list 导出数据集合
 * @param sheetName 工作表的名称
 * @return 结果
 */
public AjaxResult exportEasyExcel(List<T> list, String sheetName)
{
	String filename = encodingFilename(sheetName);
	EasyExcel.write(getAbsoluteFile(filename), clazz).sheet(sheetName).doWrite(list);
	return AjaxResult.success(filename);
}

五、修改相关Controller类

@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:post:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysPost post)
{
    List<SysPost> list = postService.selectPostList(post);
    ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
    return util.exportEasyExcel(list, "岗位数据");
}

六、导出结果

我们可以重新启动项目看看导出结果:

image-20230712154226923

还行,虽然没有ruoyi本来的好看,但是你自己愿意可以慢慢去美化。

七、合并单元格

现在我们有这么一个需求,希望导出的excel表格是下图这种样式:

image-20230712154534476

那么我们就需要重写exportEasyExcel()方法,并且使用拦截器添加合并后的单元格:

public AjaxResult exportEasyExcel(List<T> list, String sheetName)
{
    String filename = encodingFilename(sheetName);

    ExcelWriterBuilder write = EasyExcel.write(getAbsoluteFile(filename), clazz);

    // 在创建write的时候就写入需要的合并策略,不仅可以写表头,也可以写表尾
    // 此处的代码可以根据你需要填入的表头数据行数确定合并单元格的行数,根据数据部分需要导出的列数作为合并单元格的列数
    // 1、行数可以由前面传过来的表头数据动态确定,比如map的长度或者是list的长度,本案例直接在后面写死
    // 2、列数可以利用反射去读取@ExcelProperty注解的个数来动态确定,本案例也直接写死
    write.registerWriteHandler(new OnceAbsoluteMergeStrategy(0,0,1,4))
            .registerWriteHandler(new OnceAbsoluteMergeStrategy(1,1,1,4))
            .registerWriteHandler(new OnceAbsoluteMergeStrategy(2,2,1,4));

    //  在创建完sheet之后,进行拦截给合并后的单元格赋值
    ExcelWriterSheetBuilder finalSheet = write.sheet(sheetName).registerWriteHandler(new TableHeadHandler());

    // 千万不要忘记从合并的最后一行单元格的下一行开始写入数据部分
    finalSheet.relativeHeadRowIndex(3).doWrite(list);

    return AjaxResult.success(filename);
}

自定义的拦截器

// 你也可以在创建行的时候进行拦截,也可以在创建单元格的时候拦截,不同功能实现不同的接口
public class TableHeadHandler implements SheetWriteHandler {
    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder,
                                 WriteSheetHolder writeSheetHolder) {

        // 基础的excel操作,可以在此处添加表头的样式
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        Sheet sheet = workbook.getSheetAt(0);

        Row row0 = sheet.createRow(0);
        row0.createCell(0).setCellValue("第一行");
        row0.createCell(1).setCellValue("第一行的内容");

        Row row1 = sheet.createRow(1);
        row1.createCell(0).setCellValue("第二行");
        row1.createCell(1).setCellValue("第二行的内容");

        Row row2 = sheet.createRow(2);
        row2.createCell(0).setCellValue("第三行");
        row2.createCell(1).setCellValue("第三行的内容");
    }
}

八、导出结果

image-20230712162704211

最简易的效果就实现了,其他具体的美化功能和传参问题就交给你们自己去解决了,发挥自己的创造力吧!

Logo

快速构建 Web 应用程序

更多推荐