Springboot导出excel文件并下载

Springboot导出excel文件并下载



前言

在项目中,我们难免遇到需要导出的数据,而数据一般来说都是具有一定商业价值的东西,并不是每个员工都能导出的,所以不能使用前端js导出,也不是说不能,而是如果使用js导出有两个明显得不足,

  1. 你得先去判断一下该用户是否有导出的权限
  2. js导出excel的原理是捕捉页面的数据,所以有些页面没有显示的数据,就无法导出

综上所述,我们还是使用后端导出文件来的很好。


一、引入Maven包?

<dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-excelant</artifactId>
        <version>3.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>3.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.8</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.8</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
  </dependency>

二、数据库查询数据

2.1 实体类

@TableName("jms_flow_content")
@Getter
@Setter
public class JmsFlowContentEntity {
    @TableField("id")
    private Integer id;
    @TableField("name")
    private String name;
    @TableField("content")
    private String content;
    @TableField("video")
    private Integer video;
    @TableField("state")
    private Integer state;
    @TableField("create_time")
    private String createTime;
    @TableField("update_time")
    private String updateTime;
}

2.2 mapper


@Mapper
public interface JmsFlowContentMapper extends BaseMapper<JmsFlowContentEntity> {
}

我这边使用的是mybatis-plus,有兴趣的可以去学一下,如果不会的,可以按照自己熟悉的方式,mapper→xml→entity的方式获取数据

三、导出代码

这是一个serviceImpl

	@Resource
    private JmsFlowContentMapper jmsFlowContentMapper;

    public void testHSSF() throws Exception {
        // 1. 创建一个工作簿
        HSSFWorkbook wb = new HSSFWorkbook();
        // 2. 创建一个工作表
        HSSFSheet sheet = wb.createSheet();
        // 3. 获取数据库数据
        List<JmsFlowContentEntity> jmsFlowContentEntities = jmsFlowContentMapper.selectList(null);
        for (int i = 0; i < jmsFlowContentEntities.size(); i++) {
            // 4. 创建行
            HSSFRow row = sheet.createRow(i);
            // 5. 使用反射获取实体的元素的总量
            Class<? extends JmsFlowContentEntity> aClass = jmsFlowContentEntities.get(i).getClass();
            Field[] fields = aClass.getDeclaredFields();
            // 6. 行内单元格赋值
            for (int j = 0; j < fields.length; j++) {
                Field f = fields[j];
                f.setAccessible(true);
                HSSFCell cell = row.createCell(j);
                cell.setCellValue(String.valueOf(f.get(jmsFlowContentEntities.get(i))));
            }
        }
        //  7.写文件
        FileOutputStream fos = new FileOutputStream("C:/Users/Admin/Desktop/"+System.currentTimeMillis()+".xls");
        // 8.关闭流
        wb.write(fos);
        fos.close();
    }

然后你自己写一个controller引用一下这个方法,就可以了。
大功告成!

四、 补充

4.1 问题

当数据量小(比如,几千几万条)的时候可以采用同步的方式,不用考虑别的。

而当数据量大的时候(比如,几十上百万)的时候问题就暴露出来了。

首先,慢是肯定的了。少则几十秒,多则几十分钟都是有可能的。

这还是小问题,最要命的因为一个导出把系统搞挂了。。。

笔者曾经见过,因为一个导出,系统直接挂了,还严重拖慢了同一台机器上的其它应用,最终宕机了。。。

究其原因,大量数据堆积在内存中,可能会造成内存溢出。夸张一点,几百万条数据每条数据几十个字段都放到内存中,要等到全部写完这些内存才会释放。

4.2 方案

  • 针对单个工作表(sheet)的行数限制,可以分多个工作表
  • 针对单个文件太大不容易打开,可以分多个文件,最终打成压缩包
  • 针对内存溢出,可以分批导,每次导一批数据,分多次导

4.3 建议

  1. 异步下载!异步!异步!异步!
  2. 如果对样式没什么要求,也不用公式的话,强烈推荐导出CSV格式
  3. 可以采用多线程的方式,先查总数,然后分一下看需要多少个线程,每个线程读取一部数据并写入单独Excel文件; 当然,也可以多线程读,单线程写
  4. 分批导,这一点跟上一步类似
在Spring Boot中导出Excel文件有很多种方式,以下是其中一种常用的方法: 1. 首先,你需要添加Apache POI依赖到你的项目中。在你的pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> ``` 2. 创建一个Excel导出的Controller,例如: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @RestController public class ExcelController { @GetMapping("/export") public void exportExcel(HttpServletResponse response) throws IOException { // 创建一个工作簿 Workbook workbook = new XSSFWorkbook(); // 创建一个工作表 Sheet sheet = workbook.createSheet("Sheet1"); // 创建表头 Row headerRow = sheet.createRow(0); Cell headerCell = headerRow.createCell(0); headerCell.setCellValue("姓名"); // 创建数据行 Row dataRow = sheet.createRow(1); Cell dataCell = dataRow.createCell(0); dataCell.setCellValue("张三"); // 设置响应头信息 response.setHeader("Content-Disposition", "attachment; filename=example.xlsx"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 将工作簿写入到输出流 workbook.write(response.getOutputStream()); workbook.close(); } } ``` 3. 启动你的Spring Boot应用程序,访问`/export`路径,将会自动下载一个名为`example.xlsx`的Excel文件。 注意:上述示例代码只是一个简单的示例,你可以根据自己的需求来生成Excel文件。另外,还可以使用其他库如EasyExcel等来导出Excel文件
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值