欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【springboot】使用easyexcel导出Excel文件

程序员文章站 2022-03-15 16:31:31
...

业务场景:今天开发的时候遇到一个需求是将课程信息导出为本地Excel文件,选用的是目前较为方便且学习成本极低的alibaba easyexceleasyexcel仓库

 【springboot】使用easyexcel导出Excel文件

 

 导入依赖到POM文件

        <!-- poi 相关-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        <!-- easy excel 2.1.7  -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.7</version>
        </dependency>

DTO对象

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;

@Data
@HeadRowHeight(40)
public class CourseExcelDTO extends BaseRowModel implements Serializable {
    
    /**
     * 课程名称
     */
    @ColumnWidth(35)
    @ExcelProperty(value = "课程名称",index = 0)
    private String courseName;

    /**
     * 购买人数
     */
    @ColumnWidth(35)
    @ExcelProperty(value = "销量",index = 1)
    private Integer countBuy;
    
    /**
     * 原价
     */
    @ColumnWidth(35)
    @ExcelProperty(value = "销售金额",index = 2)
    private BigDecimal courseOriginal;
    
    /**
     * 学习人数
     */
    @ColumnWidth(35)
    @ExcelProperty(value = "学习人数",index = 3)
    private Integer countStudy;

}

@HeadRowHeight() 设置表头高度。

@ColumnWidth()设置列宽度。

@ExcelProperty(value = "",index = )对应字段名称和位置。

更多详细注解可参考:alibaba EasyExcel 属性注解

easyexcel工具类

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

/**
 版本2.1.7 工具类(仅导出)中可自定义样式格式等
 **/
@Component
public class ExcelUtil {
    /**
     * 导出 Excel :一个 sheet,带表头.
     *
     * @param response  HttpServletResponse
     * @param  data      数据 list,每个元素为一个 BaseRowModel
     * @param fileName  导出的文件名
     * @param sheetName 导入文件的 sheet 名
     * @param model     映射实体类,Excel 模型
     * @throws Exception 异常
     */

    public void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName, String sheetName, Class model) throws Exception {

        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10);
        // 字体
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setWrapped(true);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠中对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcel.write(getOutputStream(fileName, response), model).excelType(ExcelTypeEnum.XLSX).sheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy)
                //最大长度自适应 目前没有对应算法优化 建议注释掉不用 会出bug
//                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .doWrite(data);

    }

    /**
     * 导出文件时为Writer生成OutputStream.
     *
     * @param fileName 文件名
     * @param response response
     * @return ""
     */
    private OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e) {
            throw new Exception("导出excel表格失败!", e);
        }
    }

}

Controller层

/**
     * 根据课程ID导入数据到Excel
     * @param ids 课程ID集合
     * @return
     */
    @ApiOperation(value = "exportCourseInformation", notes = "exportCourseInformation")
    @PostMapping("/exportCourseInformation")
    public ResultDTO exportCourseInformation(HttpServletResponse resp, @ApiParam("要导出课程的id,以JSON数组形式传递") @RequestBody List<Long> ids){
        return ResultDTO.requestSuccess(courseService.exportCourseInformation(resp, ids));
    }

控制层用了ids集合用于接收需要导出的课程主键,传输到业务层进行业务操作。

注意:若控制层用了@RestController注解,会报错:Could not find acceptable representation,解决方法为将@RestController改为@Controller。具体原因可以看看这篇文章:SpringBoot导出excel数据报错Could not find acceptable representation

Service层

@Service
public class CourseServiceImpl implements CourseService {

    @Autowired
    CourseMapper courseMapper;

    @Autowired
    ExcelUtil excelUtil;

    
    @Override
    public int exportCourseInformation(HttpServletResponse resp, List<Long> ids) {
        //在数据库中查找出对应课程信息
        List<Course> courses = courseMapper.selectByIdList(ids);
        //将课程信息复制到DTO中
        List<CourseExcelDTO> courseExcelDTOS = BeanHelper.copyWithCollection(courses, CourseExcelDTO.class);
        try {
            //调用writeExcel方法进行Excel导出
            //resp:HttpServletResponse
            //courseExcelDTOS:需要导出的课程集合信息
            //文件名
            //sheet名
            //对应的DTO类
            excelUtil.writeExcel(resp, courseExcelDTOS, "课程信息", "sheet", CourseExcelDTO.class);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
        return 1;
    }


}

导出结果如下:

【springboot】使用easyexcel导出Excel文件