当前位置: 首页 > news >正文

springboot EasyExcel 实现导入导出

1. 添加依赖

确保 Maven 依赖中包含 EasyExcel 3.0.5:

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

<!-- excel工具 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

确保代码与 EasyExcel 3.0.5 及依赖的 POI 版本兼容

2. 自定义样式处理器

创建 CustomCellStyleHandler 类实现 CellWriteHandler 接口,处理标题和内容的样式:

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class CustomCellStyleHandler implements CellWriteHandler {

    private CellStyle titleStyle;
    private CellStyle contentStyle;

    private void initStyles(Workbook workbook) {
        if (titleStyle == null) {
            // 标题样式
            titleStyle = workbook.createCellStyle();
            Font titleFont = workbook.createFont();
            titleFont.setBold(true); // 加粗
            titleFont.setFontHeightInPoints((short) 14); // 字体大小
            titleStyle.setFont(titleFont);
            titleStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
            titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            titleStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 背景色
        }
        if (contentStyle == null) {
            // 内容样式
            contentStyle = workbook.createCellStyle();
            Font contentFont = workbook.createFont();
            contentFont.setFontHeightInPoints((short) 12);
            contentStyle.setFont(contentFont);
            contentStyle.setAlignment(HorizontalAlignment.CENTER);
            contentStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
            contentStyle.setBorderTop(BorderStyle.THIN); // 细边框
            contentStyle.setBorderBottom(BorderStyle.THIN);
            contentStyle.setBorderLeft(BorderStyle.THIN);
            contentStyle.setBorderRight(BorderStyle.THIN);
        }
    }

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        // 拿到poi的workbook
        Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
        initStyles(workbook);
        // 当前事件会在 数据设置到poi的cell里面才会回调
        // 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true
        if (BooleanUtils.isNotTrue(context.getHead())) {
            Cell cell = context.getCell();
            if (cell != null) {
                cell.setCellStyle(contentStyle);
            }
            // 这里要把 WriteCellData的样式清空, 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到
            // cell里面去 会导致自己设置的不一样
            context.getFirstCellData().setWriteCellStyle(null);
        }
    }
}

3. 使用处理器导出数据

在写入 Excel 时注册自定义处理器:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.hieasy.e3.common.excel.CustomCellStyleHandler;

import java.util.ArrayList;
import java.util.List;

public class ExcelWriter {
    public static void main(String[] args) {
        String fileName = "custom_style_example.xlsx";
        List<DemoData> dataList = new ArrayList<>();
        dataList.add(new DemoData("Alice", 30));
        dataList.add(new DemoData("Bob", 28));

        EasyExcel.write(fileName, DemoData.class)
                .registerWriteHandler(new CustomCellStyleHandler())
                .sheet("用户信息")
                .doWrite(dataList);
    }
}

// 数据模型类
class DemoData {
    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("年龄")
    private Integer age;

    public DemoData(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
@ApiOperation("一键导入")
    @PostMapping("/import")
    @ResponseBody
    public R<String> importExcel(@RequestPart MultipartFile file) throws IOException {
        try {
            //获取文件的输入流
            InputStream inputStream = file.getInputStream();
            List<ApiSyncLog> lst = EasyExcel.read(inputStream) //调用read方法
                    .head(ApiSyncLog.class) //对应导入的实体类
                    .sheet(0) //导入数据的sheet页编号,0代表第一个sheet页,如果不填,则会导入所有sheet页的数据
                    .headRowNumber(1) //列表头行数,1代表列表头有1行,第二行开始为数据行
                    .doReadSync(); //开始读Excel,返回一个List<T>集合,继续后续入库操作

            //模拟导入数据库操作
            for (ApiSyncLog log1:lst){
                System.out.println(log1.toString());
            }

        }catch (IOException exception){
            throw new  RuntimeException(exception);
        }
        return R.ok("Success");
    }

    @ApiOperation("一键导出")
    @GetMapping("/export")
    public void downloadExcel(HttpServletResponse response) throws IOException {
        // 设置响应头信息
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("日志文件", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

//        List<ApiSyncLog> data = new ArrayList<>();
        // 准备数据
        List<ApiSyncLog> data = apiSyncLogMapper.selectList(new QueryWrapper<ApiSyncLog>().eq("BillName", "my_jmmd"));

        // 写入数据到输出流
        EasyExcel.write(response.getOutputStream(), ApiSyncLog.class)
                .registerWriteHandler(new CustomCellStyleHandler())
                .sheet("Sheet1").doWrite(data);
    }

相关文章:

  • 麒麟系统如何安装Anaconda
  • JobScheduler省电机制
  • 【渗透测试】反弹 Shell 技术详解(二)
  • Easyocr图片识别小结
  • Flutter_学习记录_ ImagePicker拍照、录制视频、相册选择照片和视频、上传文件
  • 无监督学习——降维问题:主成分分析(PCA)详解
  • 【原创】在宝塔面板中为反向代理添加Beare认证
  • 【Linux 指北】常用 Linux 指令汇总
  • C语言中的字符串处理
  • Python :数据模型
  • Windows 图形显示驱动开发-WDDM 3.0功能- IOMMU DMA 重新映射(一)
  • NLP常见任务专题介绍(4)-ConditionalGeneration和CasualLM区别
  • 移远通信联合德壹发布全球首款搭载端侧大模型的AI具身理疗机器人
  • Kubernetes学习笔记-移除Nacos迁移至K8s
  • 一键阐述“多线程、多进程、多任务”的场景需求
  • 【Unity】在项目中使用VisualScripting
  • E-foto:开源的摄影测量与遥感图像处理工具
  • 免费blender模型网站推荐
  • CTF杂项——[SWPUCTF 2024 秋季新生赛]ez-QR
  • IP层之分片包的整合处理---BUG修复
  • 手机网站做成app/百度网盘账号登录入口
  • 门户网站和新闻网站的区别/策划营销推广方案
  • 怎么做网站主页/百度导航
  • 5000元做网站值么/百度小说
  • 电脑培训网上课程/上海seo推广外包
  • p2p网站建设公司排名/吉林关键词排名优化软件