SpringBoot整合POI导出通用Excel的方法示例

一、准备工作

1、pom依赖

在pom.xml中加入POI的依赖

<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi-ooxml</artifactId>
 <version>3.11-beta1</version>
</dependency>
<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi-ooxml-schemas</artifactId>
 <version>3.11-beta1</version>
</dependency>

2、自定义注解

自定义注解,用于定义excel单元格的相关信息,用在需要导出的类上。

大家可以根据自己的实际需求来定义更多的内容。

@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelResources {

 int order() default 9999;//定义字段在excel的单元格列坐标位置

 String title() default "";//定义列坐标对应的标题

 int cloumn() default 100;//定义列宽

 String pattern() default "";//定义日期显示格式

}

3、定义需要导出的实体

举例说明@ExcelResources 的应用场景,我们创建一个demoModel,包含姓名、年龄、性别、日期。

后边的excel导出例子也采用这个实体类来举例。

@Data
public class ExcelDemoModel {

  @ExcelResources(order=0,title = "姓名",cloumn = 10)
  private String name;

  @ExcelResources(order=1,title = "年龄",cloumn = 10)
  private Integer age;

  @ExcelResources(order=2,title = "创建时间",cloumn = 24,pattern = "yyyy-MM-dd HH:mm:ss")
  private Date createTime;

  @ExcelResources(order=3,title = "性别",cloumn = 10)
  private SexType sex;//枚举

}

4、定义导出辅助类

用于存放导出的excel对应标题和列宽

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TitleAndCloumn {

  private String title;//标题
  private int cloumn;//列宽

}

二、具体的导出方法

1、导出主要方法

@Service
public class ExcelService {

  private static float title_row_height=30;//标题行高
  private static float data_row_height=25;//数据行高

 public void exportExcel(HttpServletRequest request, HttpServletResponse response, String fileName ,List<?> excelDatas,Class<?> clz ) {

    try {

      HSSFWorkbook resultWb=new HSSFWorkbook();
      HSSFSheet sheet=resultWb.createSheet();//创建sheet

  //根据类类型信息获取导出的excel对应的标题和列宽 key-列号,value-标题和列宽
      HashMap<Integer, TitleAndCloumn> orderTitleAndCloumnMap=getTitleAndCloumnMap(clz);

      //设置列宽
      orderTitleAndCloumnMap.forEach((k,v) -> {
        sheet.setColumnWidth(k, v.getCloumn()*256);
      });

      HSSFRow row0=sheet.createRow(0);
      //设置标题行高
      row0.setHeightInPoints(title_row_height);

  //创建标题单元格格式
      HSSFCellStyle titleCellStyle=getCellStyle(resultWb,11,true,HSSFColor.BLACK.index);
      //填充标题行内容
      orderTitleAndCloumnMap.forEach((k,v) -> {
        HSSFCell row0Cell=row0.createCell(k);
        row0Cell.setCellValue(v.getTitle());
        row0Cell.setCellStyle(titleCellStyle);
      });

  //创建正文单元格格式
      HSSFCellStyle dataStyle = getCellStyle(resultWb,11,false,HSSFColor.BLACK.index);

  //将正文转换为excel数据
      int rowNum=1;
      for(Object data:excelDatas){

        HSSFRow row=sheet.createRow(rowNum++);
        row.setHeightInPoints(data_row_height);
  //获取对象值 key-列号 value-String值
        HashMap<Integer,String> orderValueMap=getValueMap(data);
        orderValueMap.forEach((k,v) ->{
          HSSFCell cell=row.createCell(k);
          cell.setCellValue(v);
          cell.setCellStyle(dataStyle);
            }
        );
      }

      String downFileName=fileName+".xls";
      response.setContentType("application/vnd.ms-excel; charset=UTF-8");// application/x-download
      response.setHeader("Content-Disposition", "attachment; "
          +encodeFileName(request, downFileName));

      OutputStream outputStream = response.getOutputStream();
      resultWb.write(outputStream);
      outputStream.flush();
      outputStream.close();
      resultWb.close();

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

  }
}

2、通过反射获取excel标题和列宽

/**
   * 获取类的属性对应单元格标题和列宽
   * @param
   * @return
   */
  private static HashMap<Integer, TitleAndCloumn> getTitleAndCloumnMap(Class<?> clz) {

    HashMap<Integer, TitleAndCloumn> orderTitleAndCloumnMap=new HashMap<>();

    Field[] fs = clz.getDeclaredFields();
    for(Field f:fs) {
      f.setAccessible(true);
      if(f.isAnnotationPresent(ExcelResources.class)) {
        Integer order=f.getAnnotation(ExcelResources.class).order();
        String title=f.getAnnotation(ExcelResources.class).title();
        int cloumn=f.getAnnotation(ExcelResources.class).cloumn();

        TitleAndCloumn titleAndCloumn=new TitleAndCloumn(title,cloumn);
        orderTitleAndCloumnMap.put(order,titleAndCloumn);
      }
    }

    return orderTitleAndCloumnMap;

  }

3、创建CellStyle

通过传入参数定义简单地CellStyle

public HSSFCellStyle getCellStyle(HSSFWorkbook workbook,int fontSize,boolean isBoleaWeight,short color){

    HSSFCellStyle style = workbook.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
    style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中

    style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    style.setBorderRight(HSSFCellStyle.BORDER_THIN);
    style.setBorderTop(HSSFCellStyle.BORDER_THIN);

    HSSFFont font = workbook.createFont();
    font.setFontHeightInPoints((short) fontSize);//字号
    font.setColor(color);//颜色
    font.setFontName("宋体");//字体

    if(isBoleaWeight){
      font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //字体加粗
    }

    style.setWrapText(true);
    style.setFont(font);

    return style;

  }

4、通过反射获取对象信息并处理成String字符串

我这里只涉及到基本数据类型和Date以及枚举的值获取和转换,小伙伴可以根据自己的实际情况进行修改。

/**
   * 获取对象的属性对应单元格坐标和值的键值对
   * @param obj
   * @return
   */
  private static HashMap<Integer, String> getValueMap(Object obj) throws IllegalAccessException {

    HashMap<Integer, String> result=new HashMap<>();

    Class<?> clz=obj.getClass();
    Field[] fs = clz.getDeclaredFields();
    for(Field f:fs) {
      f.setAccessible(true);
      if(f.isAnnotationPresent(ExcelResources.class)) {
        Integer order=f.getAnnotation(ExcelResources.class).order();
        String value="";

        Object valueObj=f.get(obj);
        if(valueObj!=null) {
   //日期格式进行特殊处理
          if(f.getType()==Date.class){

            String pattern=f.getAnnotation(ExcelResources.class).pattern();
            if(StringUtils.isEmpty(pattern)){
              pattern="yyyy-MM-dd HH:mm:ss";
            }
            SimpleDateFormat sdf=new SimpleDateFormat(pattern);
            value=sdf.format(valueObj);
          }else{
            value=valueObj.toString();//其他格式调用toString方法,这里枚举就需要定义自己的toString方法
          }

        }

        result.put(order, value);

      }
    }

    return result;
  }

5、枚举的定义

如果有用到枚举存储在数据库的小伙伴,可以自定义枚举的toString方法来实现excel导出时候相应的内容

public enum SexType {

 male("男"),
 female("女"),
 ;

 private String typeName;

 SexType(String typeName) {
 this.typeName = typeName;
 }

 @Override
 public String toString() {
 return typeName;
 }

}

6、encodeFileName

 /**
   * 根据不同的浏览器生成不同类型中文文件名编码
   *
   * @param request
   * @param fileName
   * @return
   * @throws UnsupportedEncodingException
   */
  public static String encodeFileName(HttpServletRequest request, String fileName)
      throws UnsupportedEncodingException
  {

    String new_filename = URLEncoder.encode(fileName, "UTF8").replaceAll("\\+", "%20");

    String agent = request.getHeader("USER-AGENT").toLowerCase();
    if (null != agent && -1 != agent.indexOf("msie"))
    {
      /**
       * IE浏览器,只能采用URLEncoder编码
       */
      return "filename=\"" + new_filename +"\"";
    }else if (null != agent && -1 != agent.indexOf("applewebkit")){
      /**
       * Chrome浏览器,只能采用ISO编码的中文输出
       */
      return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
    } else if (null != agent && -1 != agent.indexOf("opera")){
      /**
       * Opera浏览器只可以使用filename*的中文输出
       * RFC2231规定的标准
       */
      return "filename*=" + new_filename ;
    }else if (null != agent && -1 != agent.indexOf("safari")){
      /**
       * Safani浏览器,只能采用iso编码的中文输出
       */
      return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
    }else if (null != agent && -1 != agent.indexOf("firefox"))
    {
      /**
       * Firfox浏览器,可以使用filename*的中文输出
       * RFC2231规定的标准
       */
      return "filename*=" + new_filename ;
    } else
    {
      return "filename=\"" + new_filename +"\"";
    }
  }

三、方法调用案例

1、方法调用

public void exportExcelDemo(HttpServletRequest request, HttpServletResponse response) {

  //一系列查询处理
    List<ExcelDemoModel> demoList=new ArrayList<>();

    excelService.exportExcel(request,response,"人员信息demo",demoList,ExcelDemoModel.class);

  }

2、导出效果

到此这篇关于SpringBoot整合POI导出通用Excel的方法示例的文章就介绍到这了,更多相关SpringBoot整合POI导出Excel内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 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

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

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

  • Springboot POI导出Excel(浏览器)

    本文实例为大家分享了Springboot POI导出Excel的具体代码,供大家参考,具体内容如下 需求:页面根据查询条件导出(浏览器) 由于本次导出数据量较大,这里采用XSSFWorkbook多线程进行导出,注:XSSFWorkbook导出excel文件结尾为:".xlsx". 导出不需要返回,如有返回则会报异常! //Controller @RequestMapping("/stateExport") public void stateExport(HttpSe

  • 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

  • SpringBoot整合POI导出通用Excel的方法示例

    一.准备工作 1.pom依赖 在pom.xml中加入POI的依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.11-beta1</version> </dependency> <dependency> <groupId>org.apache.poi

  • SpringBoot整合Kotlin构建Web服务的方法示例

    今天我们尝试Spring Boot整合Kotlin,并决定建立一个非常简单的Spring Boot微服务,使用Kotlin作为编程语言进行编码构建. 创建一个简单的Spring Boot应用程序.我会在这里使用maven构建项目: <?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  • SpringBoot内存数据导出成Excel的实现方法

    前言 这是本人写的一个SpringBoot对Excel写入的方法,实测能用,待提升的地方有很多,有不足之处请多多指点. Excel2003版(后缀为.xls)最大行数是65536行,最大列数是256列. Excel2007以上的版本(后缀为.xlsx)最大行数是1048576行,最大列数是16384列. 若数据量超出行数,需要进行脚页的控制,这一点没做,因为一般100W行已够用. 提供3种方法写入: 1.根据给定的实体类列List和列名数组arr[]进行Excel写入 2.根据给定的List和k

  • SpringBoot整合EasyExcel进行大数据处理的方法详解

    目录 EasyExcel 需要的Maven 基础读案例 操作的excel 实体类 读取监听器 测试 基础写案例 实体类 测试 Excel模板方式 准备模块 实体类 测试 EasyExcel EasyExcel文档 我用过Poi和EasyPoi这些工具总体来说: POI 优点我觉得自由,但是迎来的就是复杂度,和大数据量时候性能的缺点 EasyPoi基于POI 的二次封装,解决了大部分的常用场景,简化了代码,但是特别复杂表格处理还是不行,而且性能的话和poi差不多,简单来说就是简化了Poi的操作,少

  • SpringBoot整合MyBatisPlus配置动态数据源的方法

    MybatisPlus特性 •无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 •损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 •强大的 CRUD 操作:内置通用 Mapper.通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 •支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错 •支持多种数据库:支持 MySQL.MariaDB.Ora

  • SpringBoot整合MyCat实现读写分离的方法

    MyCat一个彻底开源的,面向企业应用开发的大数据库集群.基于阿里开源的Cobar产品而研发.能满足数据库数据大量存储:提高了查询性能.文章介绍如何实现MyCat连接MySQL实现主从分离,并集成SpringBoot实现读写分离. MySQL配置主从关系 说明 192.168.0.105 Linux 数据库作为主master数据库 127.0.0.1 Window 作为从slave数据库 master主数据库配置 binlog是Mysql sever层维护的一种二进制日志,主要是用来记录对Mys

  • C#使用RenderControl将GridView控件导出到EXCEL的方法

    本文实例展示了C#使用RenderControl将GridView控件导出到EXCEL的方法,是非常实用的一个功能,分享给大家供大家参考.具体如下: 主要功能代码如下: // 把GridView输出到Excel文件 private void ExportExcel(GridView gridView, string title, string title2, string fileName) { int nHideCols = 0; //如果不想输出出某列,将Visible设为false即可 f

  • PHP将Excel导入数据库及数据库数据导出至Excel的方法

    本文实例讲述了PHP将Excel导入数据库及数据库数据导出至Excel的方法.分享给大家供大家参考.具体实现方法如下: 一.导入 导入需要使用能读取Excel的组件,网上也有比较好的组件,这里分享我使用的:下载  提取码:vxyn.(注意两个文件有引用关系) <?php //传入要导入的Excel的文件名 function import_to_DB($filename) { require_once'reader.php'; $data = new Spreadsheet_Excel_Reade

  • spring-boot整合ehcache实现缓存机制的方法

    EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. ehcache提供了多种缓存策略,主要分为内存和磁盘两级,所以无需担心容量问题. spring-boot是一个快速的集成框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 由于spring-boot无需任何样板化的配置文件,所以spring-boot集成一些其他框架时会有略微的

  • 在Vue里如何把网页的数据导出到Excel的方法

    前言: 在做后台管理的时候,我们往往有需要把网页上面的数据导出到excel这样的需求,真实的企业项目里对应一些导出财务报表.员工信息.交易记录.考勤打卡记录-等等需求,本文将对此做探讨. 开始前补充: 网上是有些牛人已经把这个功能封装成组件了,但每个人的封装逻辑五花八门,组件的功能也很有限,不一定真能完全符合自己的业务需求,找相应的API也很麻烦,存在不太敢用,不会用等问题,那么本文将教你如何自己封装,如何自己自定义相关功能,如何自定义Excel的样式 ,尤其是导出excel后自定义样式,这在一

随机推荐