SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出)

在项目持续集成的过程中,有时候需要实现报表导出和文档导出,类似于excel中这种文档的导出,在要求不高的情况下,有人可能会考虑直接导出csv文件来简化导出过程。但是导出xlsx文件,其实过程相对更复杂。解决方案就是使用poi的jar包。使用源生的poi来操作表格,代码冗余,处理复杂,同时poi的相关联的依赖还会存在版本兼容问题。所以直接使用poi来实现表格导出,维护成本大,不易于拓展。

我们需要学会站在巨人的肩膀上解决问题,jxls-poi这个就很好解决这个excel表格导出的多样化的问题。类似jsp和thymealf的模板定义,使得表格导出变得简单可控。

不多BB上代码

1.引入关键依赖包

<!-- jxls-api依赖 -->
		<dependency>
			<groupId>org.jxls</groupId>
			<artifactId>jxls-poi</artifactId>
			<version>1.0.15</version>
		</dependency>

		<dependency>
			<groupId>org.jxls</groupId>
			<artifactId>jxls</artifactId>
			<version>2.4.6</version>
		</dependency>

这里只需要两个依赖便操作excel表格了。

2.定义模板文件

新建一个excel文件,后缀名为.xlsx,在resources目录下新增一个jxls的文件夹,把模板文件放在这个文件夹下,便于后续的spring-boot的集成。

3.导出工具类

/**
 * @author machenike
 */
public class ExcelUtils {

  /***
   * excel导出到response
   * @param fileName   导出文件名
   * @param templateFile 模板文件地址
   * @param params     数据集合
   * @param response   response
   */
  public static void exportExcel(String fileName, InputStream templateFile, Map<String, Object> params,
                  HttpServletResponse response) throws IOException {
    response.reset();
    response.setHeader("Accept-Ranges", "bytes");
    OutputStream os = null;
    response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
    response.setContentType("application/octet-stream;charset=UTF-8");
    try {
      os = response.getOutputStream();
      exportExcel(templateFile, params, os);
    } catch (IOException e) {
      throw e;
    }
  }

  /**
   * 导出excel到输出流中
   * @param templateFile 模板文件
   * @param params 传入参数
   * @param os 输出流
   * @throws IOException
   */
  public static void exportExcel(InputStream templateFile, Map<String, Object> params, OutputStream os) throws IOException {
    try {
      Context context = new Context();
      Set<String> keySet = params.keySet();
      for (String key : keySet) {
        //设置参数变量
        context.putVar(key, params.get(key));
      }
      Map<String, Object> myFunction = new HashMap<>();
      myFunction.put("fun", new ExcelUtils());
      // 启动新的jxls-api 加载自定义方法
      Transformer trans = TransformerFactory.createTransformer(templateFile, os);
      JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) trans.getTransformationConfig().getExpressionEvaluator();
      evaluator.getJexlEngine().setFunctions(myFunction);

      // 载入模板、处理导出
      AreaBuilder areaBuilder = new XlsCommentAreaBuilder(trans);
      List<Area> areaList = areaBuilder.build();
      areaList.get(0).applyAt(new CellRef("sheet1!A1"), context);
      trans.write();
    } catch (IOException e) {
      throw e;
    } finally {
      try {
        if (os != null) {
          os.flush();
          os.close();
        }
        if (templateFile != null) {
          templateFile.close();
        }
      } catch (IOException e) {
        throw e;
      }
    }
  }

  /**
   * 格式化时间
   */
  public Object formatDate(Date date) {
    if (date != null) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      String dateStr = sdf.format(date);
      return dateStr;
    }
    return "--";
  }

  /**
   * 设置超链接方法
   */
  public WritableCellValue getLink(String address, String title) {
    return new WritableHyperlink(address, title);
  }
}

这个工具类中我定义两个导出用的方法
一个是直接是HttpServletResponse 导出在线下载文件
一个使用输入流导出
同时模板中还支持方法传入。

4.定义导出服务类

全局配置jxls模板的基础路径

#jxls模板的基础路径
jxls.template.path: classpath:jxls/

定义服务接口

/**
 * excel用service
 */
public interface ExcelService {

  /**
   * 导出excel,写入输出流中
   * @param templateFile
   * @param params
   * @param os
   * @return
   */
  boolean getExcel(String templateFile,Map<String,Object> params, OutputStream os);

  /**
   * 导出excel,写入response中
   * @param templateFile
   * @param fileName
   * @param params
   * @param response
   * @return
   */
  boolean getExcel(String templateFile,String fileName, Map<String,Object> params, HttpServletResponse response);

  /**
   * 导出excel,写入文件中
   * @param templateFile
   * @param params
   * @param outputFile
   * @return
   */
  boolean getExcel(String templateFile, Map<String,Object> params, File outputFile);
}

excel导出用服务实现类

/**
 * excel用serviceImpl
 */
@Service
public class ExcelServiceImppl implements ExcelService {

  private static final Logger logger = LoggerFactory.getLogger(ExcelServiceImppl.class);

  /**
   * 模板文件的基础路径
   */
  @Value("${jxls.template.path}")
  private String templatePath;

  @Override
  public boolean getExcel(String templateFile, Map<String, Object> params, OutputStream os) {
    FileInputStream inputStream = null;
    try {
      //获取模板文件的输入流
      inputStream = new FileInputStream(ResourceUtils.getFile(templatePath + templateFile));
      //导出文件到输出流
      ExcelUtils.exportExcel(inputStream, params, os);
    } catch (IOException e) {
      logger.error("excel export has error" + e);
      return false;
    }
    return true;
  }

  @Override
  public boolean getExcel(String templateFile, String fileName, Map<String, Object> params, HttpServletResponse response) {
    FileInputStream inputStream = null;
    try {
      //获取模板文件的输入流
      inputStream = new FileInputStream(ResourceUtils.getFile(templatePath + templateFile));
      //导出文件到response
      ExcelUtils.exportExcel(fileName,inputStream,params,response);
    } catch (IOException e) {
      logger.error("excel export has error" + e);
      return false;
    }
    return true;
  }

  @Override
  public boolean getExcel(String templateFile, Map<String, Object> params, File outputFile) {
    FileInputStream inputStream = null;
    try {
      //获取模板文件的输入流
      inputStream = new FileInputStream(ResourceUtils.getFile(templatePath + templateFile));
      File dFile = outputFile.getParentFile();
      //文件夹不存在时创建文件夹
      if(dFile.isDirectory()){
        if(!dFile.exists()){
          dFile.mkdir();
        }
      }
      //文件不存在时创建文件
      if(!outputFile.exists()){
        outputFile.createNewFile();
      }
      //导出excel文件
      ExcelUtils.exportExcel(inputStream, params, new FileOutputStream(outputFile));
    } catch (IOException e) {
      logger.error("excel export has error" + e);
      return false;
    }
    return true;
  }
}

如上,服务类提供了,三种导出的实现方法

  • 导出excel写入response中
  • 导出excel写入输出流中
  • 导出excel写入文件中

这三种方法足以覆盖所有的业务需求

5.编辑jxls模板

这里为方便导出最好定义与模板匹配的实体类,便于数据的装载和导出

public class UserModel {

  private Integer id;

  private String name;

  private String sex;

  private Integer age;

  private String remark;

  private Date date;

  private String link;
  }

插入标注定义模板,定义迭代对象jx:each

jx:each(items="list" var="item" lastCell="G3")

上面G3 模板中迭代的结束位置,然后用类似EL表达式的方式填充到模板当中

填写范围jx:area

jx:area(lastCell="G3")

模板编辑完成后保存即可,

6.代码测试使用

导出为本地文件

@SpringBootTest
class BlogJxlsApplicationTests {

  @Autowired
  ExcelService excelService;

  @Test
  void contextLoads() {
    Map<String, Object> params = new HashMap();
    List<UserModel> list = new ArrayList<>();
    list.add(new UserModel(1, "test01", "男", 25, "tttttttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(2, "test02", "男", 20, "tttttttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(3, "test04", "女", 25, "ttttddddasdadatttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(4, "test08", "男", 20, "ttttttdasdatttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(5, "test021", "女", 25, "ttttdatttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(7, "test041", "男", 25, "ttdadatttttttt",new Date(),"htpp://wwww.baidu.com"));

		params.put("list", list);
    excelService.getExcel("t1.xlsx", params, new File("D:\\test05.xlsx"));
  }
}

导出成功

在线导出文件

@RestController
public class TestController {
  @Autowired
  ExcelService excelService;

  @RequestMapping("test")
  public void testFile(HttpServletResponse response){
    Map<String, Object> params = new HashMap();
    List<UserModel> list = new ArrayList<>();
    list.add(new UserModel(1, "test01", "男", 25, "tttttttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(2, "test02", "男", 20, "tttttttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(3, "test04", "女", 25, "ttttddddasdadatttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(4, "test08", "男", 20, "ttttttdasdatttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(5, "test021", "女", 25, "ttttdatttttt",new Date(),"htpp://wwww.baidu.com"));
    list.add(new UserModel(7, "test041", "男", 25, "ttdadatttttttt",new Date(),"htpp://wwww.baidu.com"));

    params.put("list", list);
    excelService.getExcel("t1.xlsx",System.currentTimeMillis()+".xlsx", params,response);
  }
}

导出成功

源码地址
https://github.com/DavidLei08/BlogJxls.git

到此这篇关于SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出)的文章就介绍到这了,更多相关SpringBoot集成jxls-poi内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JXLS根据模板导出Excel实例教程

    本文实例为大家分享了JXLS根据模板导出Excel实例的具体方法,供大家参考,具体内容如下 先做模板,做成想要的格式样子保存,然后通过程序根据模板生成对应样式的Excel文件,代码简单.什么连接数据库查询然后将结果生成Excel文件就不讲了,放入List里面,然后套一下就行了,照老虎花猫. 准备: 1.相关jar包: 2.模板文件 : 开始: 1. 先实体类:Staff.java package myjxls; /** * 2014-3-17 * 8dou * 实体 */ public clas

  • SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出)

    在项目持续集成的过程中,有时候需要实现报表导出和文档导出,类似于excel中这种文档的导出,在要求不高的情况下,有人可能会考虑直接导出csv文件来简化导出过程.但是导出xlsx文件,其实过程相对更复杂.解决方案就是使用poi的jar包.使用源生的poi来操作表格,代码冗余,处理复杂,同时poi的相关联的依赖还会存在版本兼容问题.所以直接使用poi来实现表格导出,维护成本大,不易于拓展. 我们需要学会站在巨人的肩膀上解决问题,jxls-poi这个就很好解决这个excel表格导出的多样化的问题.类似

  • springboot快速集成mybatis-plus的详细教程

    简介 Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发.提高效率而生.这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网.那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA. springBoot快速集成mybatis-plus 一.pom文件引入mybatis-plus依赖 <dependenc

  • 手把手教你SpringBoot快速集成Swagger的配置过程

    导语 相信大家无论是做前端还是做后端的,都被接口接口文档所折磨过,前端抱怨接口文档和后端给的不一致,后端抱怨写接口文档很麻烦,所以Swagger就诞生了.直接配置即可自动生成接口文档,而且提供了高效的API测试 话不多说直接开干 导入SpringBoot集成Swagger所需要的依赖 <!--web方便测试--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g

  • SpringBoot快速集成Logback日志组件

    目录 前言 引入: 配置: 开发: 结语 前言 在前一节的分享中,慕歌向大家介绍了如何使用spring boot 实现简单的邮寄发送服务,用于验证码服务或者是通知服务.如果大家有兴趣,慕歌还想向大家进一步分享,如何在使用第三方服务,实现手机短信通知服务,就是那个我们每天都会使用到的短信验证码,通知服务.这一节慕歌想带来spring boot日志系统的分享,以及慕歌自己的实现的简易日志记录,慕歌会将日志同时保存在文件和数据库之中. 引入: 如果我们使用 logback 就无需额外引入依赖,在spr

  • Java SpringBoot快速集成SpringBootAdmin管控台监控服务详解

    目录 1.初识SpringBootAdmin 2.搭建服务端--POM文件中添加相关依赖 3.修改服务端application启动类 4.配置security安全信息 5.启动server服务端 6.搭建client客户端 总结 SpringBootAdmin是一个针对 Spring Boot 的 Actuator 接口进行 UI 美化封装的监控工具,它可以在列表中浏览所有被监控 spring-boot 项目的基本信息.详细的 Health 信息.内存信息.JVM 信息.垃圾回收信息.各种配置信

  • AndroidStudio4.1 自定义模板的使用方法

    AndroidStudio4.0之前,可以在template的文件夹里使用freemarker的自定义模板,可以在AndroidStudio的文件夹中,随意的添加适合自己的自定义模板 但是从4.1版本开始提供新的方式,Geminio,用Kotlin的形式编写新的template,而且需要使用插件的形式,才能使用自定义的模板,摸索了好几天,终于解决了. 我的项目是使用MVVM的开发框架,每次在编写一个新的页面的时候,就需要新建四个文件Activity/Fragment, ViewModel, Re

  • springboot集成shiro遭遇自定义filter异常的解决

    目录 springboot集成shiro遭遇自定义filter异常 1.用maven添加shiro 2.配置shiro 3.实现自定义的Realm.filter.SubjectFactory等 4.重点记录filter配置中出现的问题 5.解决方案 shiro自定义异常无效 springboot集成shiro遭遇自定义filter异常 首先简述springboot使用maven集成shiro 1.用maven添加shiro <!--shiro--> <dependency> <

  • 使用Springboot自定义注解,支持SPEL表达式

    目录 Springboot自定义注解,支持SPEL表达式 1.自定义注解 2.使用AOP拦截方法,解析注解参数 自定义注解结合切面和spel表达式 自定义一个注解 自定义一个service类,在需要拦截的方法上加上@Log注解 写一个自定义切面 pom文件的依赖 测试 增加内容 Springboot自定义注解,支持SPEL表达式 举例,自定义redis模糊删除注解 1.自定义注解 import java.lang.annotation.ElementType; import java.lang.

  • Spring Boot 快速集成 Redis的方法

    Spring Boot 如何快速集成 Redis?没错,栈长本文教你,让大家少走弯路! 添加依赖 使用像 Redis 这类的 NoSQL 数据库就必须要依赖 spring-data-redis 这样的能力包,开箱即用,Spring Boot 中都封装好了: 引入spring-boot-starter-data-redis: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>

  • SpringBoot如何基于POI-tl和word模板导出庞大的Word文件

    目录 前言 知识准备 什么是poi-tl poi-tl的TDO模式 Template:模板 Data-model:数据 Output:输出 实现案例 Pom依赖 导出基于template的word 导出markdown为word 前言 poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性.本文主要介绍通过SpringBoot集成poi-tl实现模板方式的Word导出功能. 知识准备 需要理解文件上

随机推荐