Spring Boot Excel文件导出下载实现代码

Spring Boot Excel 文件导出

目标:

实现Excel文件的直接导出下载,后续开发不需要开发很多代码,直接继承已经写好的代码,增加一个Xml配置就可以直接导出。

实现:

1、抽象类 BaseExcelView 继承 webmvc 的  AbstractXlsxStreamingView 抽象类, AbstractXlsxStreamingView 是webmvc继承了最顶层View接口,是可以直接大量数据导出的不会造成内存泄漏问题,即 SXSSFWorkbook 解决了内存问题, 导出只支持xlsx类型文件。

抽象类代码 BaseExcelView :

public abstract class BaseExcelView extends AbstractXlsxStreamingView {
  private static final Logger logger = LoggerFactory.getLogger(BaseExcelView.class);
  /**
   * 获取导出文件名
   *
   * @return
   */
  abstract protected String getFileName();
  /**
   * 获取表单名称
   *
   * @return
   */
  abstract protected String getSheetName();
  /**
   * 获取标题栏名称
   *
   * @return
   */
  abstract protected String[] getTitles();
  /**
   * 获取列宽
   *
   * @return
   */
  abstract protected short[] getColumnWidths();
  /**
   * 构造内容单元格
   *
   * @param sheet
   */
  abstract protected void buildContentCells(Sheet sheet);
  @Override
  protected void buildExcelDocument(
      Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response)
      throws Exception {
    // 构造标题单元格 SXSSFWorkbook
    Sheet sheet = buildTitleCells(workbook);
    // 构造内容单元格
    buildContentCells(sheet);
    // 设置响应头
    setResponseHead(request, response);
  }
  /**
   * 设置响应头
   *
   * @param response
   * @throws IOException
   */
  protected void setResponseHead(HttpServletRequest request,
                  HttpServletResponse response) throws IOException {
    // 文件名
    String fileName = getFileName();
    String userAgent = request.getHeader("user-agent").toLowerCase();
    logger.info("客户端请求头内容:");
    logger.info("user-agent\t值: {}", userAgent);
    if (userAgent != null) {
      if (userAgent.contains("firefox")) {
        // firefox有默认的备用字符集是西欧字符集
        fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
      } else if (userAgent.contains("webkit") && (userAgent.contains("chrome") || userAgent.contains("safari"))) {
        // webkit核心的浏览器,主流的有chrome,safari,360
        fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
      } else {
        // 新老版本的IE都可直接用URL编码工具编码后输出正确的名称,无乱码
        fileName = URLEncoder.encode(fileName, "UTF-8");
      }
    }
    //响应头信息
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/ms-excel; charset=UTF-8");
    response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");
  }
  /**
   * 构造标题单元格
   *
   * @param
   * @return
   */
  protected Sheet buildTitleCells(Workbook workbook) {
    // 表单名称
    String sheetName = getSheetName();
    // 标题名称
    String[] titles = getTitles();
    // 列宽
    short[] colWidths = getColumnWidths();
    // 创建表格
    Sheet sheet = workbook.createSheet(sheetName);
    // 标题单元格样式
    CellStyle titleStyle = getHeadStyle(workbook);
    // 默认内容单元格样式
    CellStyle contentStyle = getBodyStyle(workbook);
    // 标题行
    Row titleRow = sheet.createRow(0);
    // 创建标题行单元格
    for (int i = 0; i < titles.length; i++) {
      // 标题单元格
      Cell cell = titleRow.createCell((short) i);
      cell.setCellType(CellType.STRING);
      cell.setCellValue(new XSSFRichTextString(titles[i]));
      cell.setCellStyle(titleStyle);
      // 设置列宽
      sheet.setColumnWidth((short) i, (short) (colWidths[i] * 256));
      // 设置列默认样式
      sheet.setDefaultColumnStyle((short) i, contentStyle);
    }
    return sheet;
  }
  /**
   * 设置表头的单元格样式
   */
  public CellStyle getHeadStyle(Workbook workbook) {
    // 创建单元格样式
    CellStyle cellStyle = workbook.createCellStyle();
    // 设置单元格的背景颜色为淡蓝色
    cellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.index);
    // 设置填充字体的样式
    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    // 设置单元格居中对齐
    cellStyle.setAlignment(HorizontalAlignment.CENTER);
    // 设置单元格垂直居中对齐
    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    // 创建单元格内容显示不下时自动换行
    cellStyle.setWrapText(true);
    // 设置单元格字体样式
    Font font = workbook.createFont();
    // 字号
    font.setFontHeightInPoints((short) 12);
    // 加粗
    font.setBold(true);
    // 将字体填充到表格中去
    cellStyle.setFont(font);
    // 设置单元格边框为细线条(上下左右)
    cellStyle.setBorderLeft(BorderStyle.THIN);
    cellStyle.setBorderBottom(BorderStyle.THIN);
    cellStyle.setBorderRight(BorderStyle.THIN);
    cellStyle.setBorderTop(BorderStyle.THIN);
    return cellStyle;
  }
  /**
   * 设置表体的单元格样式
   */
  public CellStyle getBodyStyle(Workbook workbook) {
    // 创建单元格样式
    CellStyle cellStyle = workbook.createCellStyle();
    // 设置单元格居中对齐
    cellStyle.setAlignment(HorizontalAlignment.CENTER);
    // 设置单元格居中对齐
    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    // 创建单元格内容不显示自动换行
    cellStyle.setWrapText(true);
    //设置单元格字体样式字体
    Font font = workbook.createFont();
    // 字号
    font.setFontHeightInPoints((short) 10);
    // 将字体添加到表格中去
    cellStyle.setFont(font);
    // 设置单元格边框为细线条
    cellStyle.setBorderLeft(BorderStyle.THIN);
    cellStyle.setBorderBottom(BorderStyle.THIN);
    cellStyle.setBorderRight(BorderStyle.THIN);
    cellStyle.setBorderTop(BorderStyle.THIN);
    return cellStyle;
  }
}

Excel导出实现 1: 可以直接继承 BaseExcelView  实现定义的方法 eg:

public class CheckExcelView extends BaseExcelView {
  private List<T> vo;
  public CheckExcelView(List<T> vo) {
   this.vo= vo;
  }
  @Override
  protected String getFileName() {
   String time = DateUtils.getLocalFullDateTime14();
   return "导出文件" + time;
  }
  @Override
  protected String getSheetName() {
    return "报表";
  }
  @Override
  protected String[] getTitles() {
   return new String[] { "申请时间"};
  }
  @Override
  protected short[] getColumnWidths() {
   return new short[] { 20};
  }
  @Override
  protected void buildContentCells(Sheet sheet) {
   DecimalFormat df = new DecimalFormat("0.00");
   int rowNum = 1;
   for (T o : vO) {
     Row crow = sheet.createRow(rowNum++);
     crow.createCell(0).setCellValue(o.getApplicationDate()));
   }
  }
}

导出实现 2: XML配置导出

1、需要定义XML的配置 export-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <table id="demo" name="测试">
    <columns>
      <column id="name" name="名称" width="40"></column>
    </columns>
  </table>
</configuration>

2、XMl解析配置

@Root
public class Export {
  @ElementList(entry = "table", inline = true)
  private List<Table> table;
  public List<Table> getTable() {
    return table;
  }
  public void setTable(List<Table> table) {
    this.table = table;
  }
  public static class Table {
    @Attribute
    private String id;
    @Attribute
    private String name;
    @ElementList(entry = "column")
    private List<Column> columns;
    public String getId() {
      return id;
    }
    public void setId(String id) {
      this.id = id;
    }
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name = name;
    }
    public List<Column> getColumns() {
      return columns;
    }
    public void setColumns(List<Column> columns) {
      this.columns = columns;
    }
  }
  public static class Column {
    @Attribute
    private String id;
    @Attribute
    private String name;
    @Attribute
    private short width;
    @Attribute(required = false)
    private String mapping;
    public String getId() {
      return id;
    }
    public void setId(String id) {
      this.id = id;
    }
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name = name;
    }
    public String getMapping() {
      return mapping;
    }
    public void setMapping(String mapping) {
      this.mapping = mapping;
    }
    public short getWidth() {
      return width;
    }
    public void setWidth(short width) {
      this.width = width;
    }
  }
}

3、解析XMl方法配置

@Service
public class IExportService {
  private Export tables;
  private Map<String, Export.Table> tableMap;
  @SuppressWarnings("rawtypes")
  @PostConstruct
  public void init() throws Exception {
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("export-config.xml");
    Serializer serializer = new Persister();
    tables = serializer.read(Export.class, inputStream);
    tableMap = new HashMap<>();
    for (Export.Table table : tables.getTable()) {
      tableMap.put(table.getId(), table);
    }
  }
  public Export.Table getTable(String key) {
    return tableMap.get(key);
  }
}

4、导出基础  ExcelExportView 代码实现

public class ExcelExportView extends BaseExcelView {
  private String[] titles;
  private short[] columnWidths;
  List<Map<String, Object>> results;
  private Export.Table table;
  private IExportService iExportService;
  @Override
  protected String getFileName() {
    return table.getName();
  }
  @Override
  protected String getSheetName() {
    return table.getName();
  }
  @Override
  protected String[] getTitles() {
    return this.titles;
  }
  @Override
  protected short[] getColumnWidths() {
    return this.columnWidths;
  }
  public ExcelExportView() {
    this.iExportService = ApplicationContextProvider.getBean(IExportService.class);
  }
  @Override
  protected void buildContentCells(Sheet sheet) {
    int dataIndex = 1;
    if(CollectionUtils.isEmpty(results)){
      return;
    }
    for (Map<String, Object> data : results) {
      Row row = sheet.createRow(dataIndex++);
      for (int i = 0; i < table.getColumns().size(); i++) {
        Export.Column column = table.getColumns().get(i);
        Cell cell = row.createCell(i);
        Object value = data.get(column.getId());
        if (value == null) {
          value = "";
        }
        cell.setCellValue(new XSSFRichTextString(value.toString()));
      }
    }
  }
  public void exportExcel(String key, List<Map<String, Object>> results) {
    this.table = iExportService.getTable(key);
    if (null == table) {
      return;
    }
    this.results = results;
    this.titles = new String[table.getColumns().size()];
    this.columnWidths = new short[table.getColumns().size()];
    for (int i = 0; i < table.getColumns().size(); i++) {
      Export.Column column = table.getColumns().get(i);
      titles[i] = column.getName();
      columnWidths[i] = column.getWidth();
    }
  }
}

最后:导出Controller代码实现

@RequestMapping(path = "/export", method = RequestMethod.GET, produces = "application/octet-stream;charset=UTF-8")
public @ResponseBody
ModelAndView export(){
  Long loginComId = loginContext.getCompany().getId();
  List<T> list = new ArrayList<>();
  ExcelExportView exportView = new ExcelExportView();
  exportView.exportExcel("XMl中表的ID", BeanUtils.objectToMapList(list));
  return new ModelAndView(exportView);
<em id="__mceDel"><em id="__mceDel">}</em></em>

总结

以上所述是小编给大家介绍的Spring Boot  Excel文件导出下载实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 使用Vue+Spring Boot实现Excel上传功能

    1.使用Vue-Cli创建前端项目 运用vue-cli工具可以很轻松地构建前端项目,当然,使用WebStorm来构建会更加简洁(如图).本文推荐使用WebStorm,因为在后续开发中,IDE会使我们的开发更加简洁.部分配置如图: 2.Navbar编写 作为一个WebApp,Navbar作为应用的导航栏是必不可少的.在本项目中,笔者引入了bootstrap对Navbar进行了轻松地构建.在vue中我们需要在components文件夹中将我们的组件加进去,对于本工程来说,Navbar是我们要加入的第

  • Springboot使用POI实现导出Excel文件示例

    前面讲述了使用POI导出Word文件和读取Excel文件,这两个例子都相对简单,接下来要讲述的使用POI导出Excel文件要复杂得多,内容也会比较长. 创建表头信息 表头信息用于自动生成表头结构及排序 public class ExcelHeader implements Comparable<ExcelHeader>{ /** * excel的标题名称 */ private String title; /** * 每一个标题的顺序 */ private int order; /** * 说对

  • Springboot上传excel并将表格数据导入或更新mySql数据库的过程

    本文主要描述,Springboot-mybatis框架下上传excel,并将之导入mysql数据库的过程,如果用户id已存在,则进行更新修改数据库中该项信息,由于用到的是前后端分离技术,这里记录的主要是后端java部分,通过与前端接口进行对接实现功能,使用layui等前端框架与之对接,也可以自己写前端代码,本文以Controller开始,从导入过程开始讲述,其中包括字典表的转换 1.在pom.xml文件中导入注解,主要利用POI <dependency> <groupId>org.

  • springboot实现上传并解析Excel过程解析

    添加pom依赖 <!-- excel解析包 --> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <!--处理2003 excel--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16<

  • spring boot读取Excel操作示例

    本文实例讲述了spring boot读取Excel操作.分享给大家供大家参考,具体如下: 首先引入相关依赖 <!--解析office相关文件--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependenc

  • SpringBoot使用POI进行Excel下载

    本文实例为大家分享了SpringBoot使用POI进行Excel下载的具体代码,供大家参考,具体内容如下 使用poi处理Excel特别方便,此处将处理Excel的代码分享出来. 1.maven引用 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependenc

  • Spring 实现excel及pdf导出表格示例

    整理文档,搜刮出一个Spring 实现excel及pdf导出表格的代码,稍微整理精简一下做下分享. excel 导出: package light.mvc.utils.excel; import java.util.Date; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse

  • 详解poi+springmvc+springjdbc导入导出excel实例

    工作中常遇到导入导出excel的需求,本獂有一简答实例与大家分享. 废话不多说, 1.所需jar包: 2.前端代码: ieport.jsp: <%@page import="java.util.Date"%> <%@ page language="java" contentType="text/html; charset=utf-" pageEncoding="utf-"%> <!DOCTYPE

  • java springboot poi 从controller 接收不同类型excel 文件处理

    根据poi接收controller层的excel文件导入 可使用后缀名xls或xlsx格式的excel. 1.pom引入 <!-- poi 操作Excel --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <d

  • SpringMVC上传和解析Excel方法

    示例:导入相关数据(Excel文件),相关的文件数据编辑好. XML文件配置 再spring的xml文件中配置要上传文件的大小 <!-- 上传文件拦截,设置最大上传文件大小 10M=10*1024*1024(B)=10485760 bytes --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver&qu

随机推荐