spring boot使用easyExcel导出excel踩坑之旅

需求

前台页面显示预约列表,点击导出按钮,导出数据

实现

使用easyExcel来实现这个需求
EasyExcel使用说明
alibaba/easyexcel

第一,创建实体类,写入excel的数据,OrderExcelEntity

public class OrderExcelEntity  {
    //设置表头名称
    /**
     * 姓名
     */
    @ExcelProperty("姓名")
    private String  name;

    /**
     * 证件号码
     */
    @ExcelProperty("证件号码")
    private String  cardId;

    /**
     * 居住地
     */
    @ExcelProperty("居住地")
    private String  address;

    /**
     * 学校
     */
    @ExcelProperty("学校")
    private String  school;

    /**
     * 接种点编码
     */
    @ExcelProperty("接种点编码")
    private String  orgCode;

    /**
     * 接种点名称
     */
    @ExcelProperty("接种点名称")
    private String  orgName;

    /**
     * 预约日期
     */
    @ExcelProperty("预约日期")
    private String  appiontmentDate;

    /**
     * 预约时段
     */
    @ExcelProperty("预约时段")
    private String  appointmentPeriod;


    /**
     * 疫苗
     */
    @ExcelProperty("疫苗")
    private String  vaccineName;

    /**
     * 监护人姓名
     */
    @ExcelProperty("监护人姓名")
    private String  guardianName;

    /**
     * 监护人手机号码
     */
    @ExcelProperty("监护人手机号码")
    private String  guardianMobile;

    /**
     * 预约状态,1预约,0取消预约
     */
    @ExcelProperty("预约状态")
    private String  appiontmentState;

    /**
     * 取消预约时间
     */
    @ExcelProperty("取消预约时间")
    private String  cancleTime;

    public String getName() {
        return name;
    }

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

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

    public String getOrgCode() {
        return orgCode;
    }

    public void setOrgCode(String orgCode) {
        this.orgCode = orgCode;
    }

    public String getOrgName() {
        return orgName;
    }

    public void setOrgName(String orgName) {
        this.orgName = orgName;
    }

    public String getAppiontmentDate() {
        return appiontmentDate;
    }

    public void setAppiontmentDate(String appiontmentDate) {
        this.appiontmentDate = appiontmentDate;
    }

    public String getAppointmentPeriod() {
        return appointmentPeriod;
    }

    public void setAppointmentPeriod(String appointmentPeriod) {
        this.appointmentPeriod = appointmentPeriod;
    }

    public String getVaccineName() {
        return vaccineName;
    }

    public void setVaccineName(String vaccineName) {
        this.vaccineName = vaccineName;
    }

    public String getGuardianName() {
        return guardianName;
    }

    public void setGuardianName(String guardianName) {
        this.guardianName = guardianName;
    }

    public String getGuardianMobile() {
        return guardianMobile;
    }

    public void setGuardianMobile(String guardianMobile) {
        this.guardianMobile = guardianMobile;
    }

    public String getAppiontmentState() {
        return appiontmentState;
    }

    public void setAppiontmentState(String appiontmentState) {
        this.appiontmentState = appiontmentState;
    }

    public String getCancleTime() {
        return cancleTime;
    }

    public void setCancleTime(String cancleTime) {
        this.cancleTime = cancleTime;
    }
}

第二,在service中编写生成excel的方法
第一种实现方式:指定文件位置,在本地生成excel,然后写入数据

 /**
     * 写入excel
     * @return
     */
    public ComServiceResVo writeExcel(String fileName, ServletOutputStream outputStream) {

        List<OrderExcelEntity> list = new ArrayList<>();
        List<VaccineOrderEntity> orders = repository.findAllByLogicDelFalse();
        for (VaccineOrderEntity order : orders) {
            OrderExcelEntity data = new OrderExcelEntity();
            data.setName(order.getName()==null?"":order.getName()) ;
            data.setCardId(order.getCardId()==null?"":order.getCardId()) ;
            data.setAddress(order.getAddress()==null?"":order.getAddress()) ;
            data.setSchool(order.getSchool()==null?"":order.getSchool()) ;
            data.setOrgCode(order.getOrgCode()==null?"":order.getOrgCode()) ;
            data.setOrgName(order.getOrgName()==null?"":order.getOrgName()) ;
            data.setAppiontmentDate(order.getAppiontmentDate()==null?"":order.getAppiontmentDate()) ;
            data.setAppointmentPeriod(order.getAppointmentPeriod()==null?"":order.getAppointmentPeriod()) ;
            data.setVaccineName(order.getVaccineName()==null?"":order.getVaccineName()) ;
            data.setGuardianName(order.getGuardianName()==null?"":order.getGuardianName()) ;
            data.setGuardianMobile(order.getGuardianMobile()==null?"":order.getGuardianMobile()) ;
            data.setAppiontmentState(order.getAppiontmentState()==0?"预约取消":"预约成功") ;
            data.setCancleTime(order.getCancleTime()==null?"":order.getCancleTime()) ;
            list.add(data);
        }

       String fileName = "D:\\预约详情"+System.currentTimeMillis()+".xlsx";
        File file=new File(fileName);
        if (!file.exists()){

            try {
                //可以表示xls和xlsx格式文件的类
                XSSFWorkbook  workbook = new XSSFWorkbook();
                try {
                    //新创建的xls需要新创建新的工作簿,offine默认创建的时候会默认生成三个sheet
                    Sheet sheet = workbook.createSheet("预约详情");
                    sheet.setDefaultColumnWidth((short) 100);
                    FileOutputStream out = new FileOutputStream(fileName);
                    workbook.write(out);

                    System.out.println("createWorkBook success");
                    EasyExcel.write(fileName, OrderExcelEntity.class).sheet("预约详情").doWrite(list);
                    out.close();
                   return ComServiceResVo.ok("导出成功,保存在"+fileName);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }  catch (Exception e) {
                e.printStackTrace();
            }

        }
       return ComServiceResVo.badRequest("导出失败");
    }

坑1:使用File createNewFile()方法创建 xlsx打不开
本地生产文件,一般是使用File类,先通过exist()方法来检测,然后通过createNewFile()方法生成。刚开始是使用这些方法生成了.xlsx文件,然后报错,刚开始以为是easyExcel方法写错的原因,后来发现生成的xlsx文件根本打不开,所以,如果要生成xlsx文件,不能使用File方法,要使用poi方式(XSSFWorkbook),poi提供了HSSFWorkbook和XSSFWorkbook两个实现类。区别在于HSSFWorkbook是针对.xls文件,XSSFWorkbook是针对.xslx文件。
创建excel文件
坑2使用XSSFWorkbook创建excel报错
pom.xml需要引入两个poi依赖

 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
        
<properties>
      ...
        <poi.version>4.1.2</poi.version>
    </properties>

坑3报错 Can not close IO
原因要检查三个地方
1.检查:查看poi版本是否冲突
2.检查是否缺少依赖版本
3.检查poi的版本要大于等于3.17版本

我原来的版本比较小,所以poi版本要大于3.17,可以从官网上查看最新版本号
官网
第三,controller提供对外方法

 @RequestMapping(value = "/excel", method = RequestMethod.GET)
 @ResponseBody
  public ComServiceResVo writeExcel() {
   
     return service.writeExcel();

    }

第四,js调用接口

     $("#excel").click(function (e) {
         $.ajax({
                url: _CONTEXT_PATH + "mg/vaccine/order/excel",


                error: function (errorRes, textStatus, errorThrown) {
                    if (errorRes.status == 401) {
                        window.location.replace(_CONTEXT_PATH + errorRes.responseText);
                    } else {
                        swal({title: "oops !!", text: errorRes.responseText, type: "error",}, function () {});
                    }
                },
                success:function (data) {
                    swal({title: "oops !!", text: data.body, type: "success",}, function () {});
                }
            })
            }

这种实现的方式就是,前台页面点击导出,会在后台中指定位置生成文件,然后在前台弹框进行提示,"导出成功,保存在"XXXX.xlsx

另一种实现方式

不在本地保存指定位置,用户点击导出,直接从网页上下载
service中方法修改

public ComServiceResVo writeExcel(String fileName, ServletOutputStream outputStream) {

        List<OrderExcelEntity> list = new ArrayList<>();
        List<VaccineOrderEntity> orders = repository.findAllByLogicDelFalse();
        for (VaccineOrderEntity order : orders) {
            OrderExcelEntity data = new OrderExcelEntity();
            data.setName(order.getName()==null?"":order.getName()) ;
            data.setCardId(order.getCardId()==null?"":order.getCardId()) ;
            data.setAddress(order.getAddress()==null?"":order.getAddress()) ;
            data.setSchool(order.getSchool()==null?"":order.getSchool()) ;
            data.setOrgCode(order.getOrgCode()==null?"":order.getOrgCode()) ;
            data.setOrgName(order.getOrgName()==null?"":order.getOrgName()) ;
            data.setAppiontmentDate(order.getAppiontmentDate()==null?"":order.getAppiontmentDate()) ;
            data.setAppointmentPeriod(order.getAppointmentPeriod()==null?"":order.getAppointmentPeriod()) ;
            data.setVaccineName(order.getVaccineName()==null?"":order.getVaccineName()) ;
            data.setGuardianName(order.getGuardianName()==null?"":order.getGuardianName()) ;
            data.setGuardianMobile(order.getGuardianMobile()==null?"":order.getGuardianMobile()) ;
            data.setAppiontmentState(order.getAppiontmentState()==0?"预约取消":"预约成功") ;
            data.setCancleTime(order.getCancleTime()==null?"":order.getCancleTime()) ;
            list.add(data);
        }


        // LocalDateTime localDate=LocalDateTime.now();
      /*  String fileName = "D:\\预约详情"+System.currentTimeMillis()+".xlsx";
        File file=new File(fileName);
        if (!file.exists()){

            try {
                //可以表示xls和xlsx格式文件的类
                XSSFWorkbook  workbook = new XSSFWorkbook();
                try {
                    //新创建的xls需要新创建新的工作簿,offine默认创建的时候会默认生成三个sheet
                    Sheet sheet = workbook.createSheet("预约详情");
                    sheet.setDefaultColumnWidth((short) 100);
                    FileOutputStream out = new FileOutputStream(fileName);
                    workbook.write(out);

                    System.out.println("createWorkBook success");
                    EasyExcel.write(fileName, OrderExcelEntity.class).sheet("预约详情").doWrite(list);
                    out.close();
                   return ComServiceResVo.ok("导出成功,保存在"+fileName);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }  catch (Exception e) {
                e.printStackTrace();
            }

        }*/


            try {
                //可以表示xls和xlsx格式文件的类
              //  XSSFWorkbook  workbook = new XSSFWorkbook();
                try {
                    //新创建的xls需要新创建新的工作簿,offine默认创建的时候会默认生成三个sheet
                  //  Sheet sheet = workbook.createSheet("预约详情");
                   // sheet.setDefaultColumnWidth((short) 100);
                   // workbook.write(outputStream);

                   EasyExcel.write(outputStream, OrderExcelEntity.class).sheet("预约详情").doWrite(list);
                    outputStream.close();

                    return ComServiceResVo.ok("导出成功");
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }  catch (Exception e) {
                e.printStackTrace();
            }



       return ComServiceResVo.badRequest("导出失败");
    }
EasyExcel.write(outputStream, OrderExcelEntity.class).sheet("预约详情").doWrite(list);
                    outputStream.close();

这句话是关键,直接将数据写入到outputStream中,不用创建文件
controller方法修改

  @RequestMapping(value = "/excel", method = RequestMethod.GET)
   // @ResponseBody
    public ComServiceResVo writeExcel(HttpServletResponse response) {
        response.setContentType("application/binary;charset=ISO8859_1");
        try {
            //获取选中的column
            ServletOutputStream outputStream = response.getOutputStream();
            String fileName = new String(("预约详情").getBytes(), "ISO8859_1") +
                    DateUtil.fromInstantToString("MMddHHmm", Instant.ofEpochMilli(System.currentTimeMillis()));
            response.setCharacterEncoding("utf-8");
            // 组装附件名称和格式
            response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");

            service.writeExcel(DateUtil.fromInstantToString("MMddHHmm", Instant.ofEpochMilli(System.currentTimeMillis())),
                    outputStream);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
     // return service.writeExcel();

    }

js方法修改

  $("#excel").click(function (e) {
          /*  $.ajax({
                url: _CONTEXT_PATH + "mg/vaccine/order/excel",


                error: function (errorRes, textStatus, errorThrown) {
                    if (errorRes.status == 401) {
                        window.location.replace(_CONTEXT_PATH + errorRes.responseText);
                    } else {
                        swal({title: "oops !!", text: errorRes.responseText, type: "error",}, function () {});
                    }
                },
                success:function (data) {
                    swal({title: "oops !!", text: data.body, type: "success",}, function () {});
                }
            })*/

            e.preventDefault();
            window.location.href = _CONTEXT_PATH + "mg/vaccine/order/excel";
        });

如果excel宽度不合适,可以设置样式
在实体类上添加注解

@ContentRowHeight(20)
@HeadRowHeight(20)
@ColumnWidth(20)
public class OrderExcelEntity  {

参考

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot使用EasyExcel导出动态数据为Excel文件的代码如下: 1. 首先,我们需要导入`easyexcel`的依赖。在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.3.0</version> </dependency> ``` 2. 创建一个Excel工具类,用于导出Excel文件。假设我们已经有一个名为`ExcelUtil`的工具类。 ```java import com.alibaba.excel.EasyExcel; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.util.List; @Component public class ExcelUtil { public void export(HttpServletResponse response, List<Object> data) 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"); // 导出Excel文件 EasyExcel.write(response.getOutputStream(), Object.class).sheet("Sheet1").doWrite(data); } public void exportTemplate(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"); // 导出模板文件 InputStream inputStream = getClass().getClassLoader().getResourceAsStream("template.xlsx"); EasyExcel.write(response.getOutputStream()).withTemplate(inputStream).sheet().doWrite(null); } } ``` 3. 创建一个Controller类,用于处理导出Excel的请求。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("/excel") public class ExcelController { @Autowired private ExcelUtil excelUtil; @GetMapping("/export") public void exportExcel(HttpServletResponse response) throws IOException { // 模拟动态数据,实际场景中可以根据业务需求获取数据 List<Object> data = new ArrayList<>(); data.add("数据1"); data.add("数据2"); data.add("数据3"); // 导出Excel文件 excelUtil.export(response, data); } @GetMapping("/template") public void exportTemplate(HttpServletResponse response) throws IOException { // 导出Excel模板文件 excelUtil.exportTemplate(response); } } ``` 以上代码演示了使用Spring BootEasyExcel导出动态数据为Excel文件的过程。在Controller中,我们可以根据实际业务需求获取数据,并调用`ExcelUtil`中的方法实现导出操作。同时,我们也提供了导出Excel模板文件的方法,以方便用户进行数据录入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值