热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

这篇文章主要介绍了SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

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

不多BB上代码

1.引入关键依赖包


		
			org.jxls
			jxls-poi
			1.0.15
		

		
			org.jxls
			jxls
			2.4.6
		

这里只需要两个依赖便操作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 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 params, OutputStream os) throws IOException {
    try {
      Context cOntext= new Context();
      Set keySet = params.keySet();
      for (String key : keySet) {
        //设置参数变量
        context.putVar(key, params.get(key));
      }
      Map 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 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 params, OutputStream os);

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

  /**
   * 导出excel,写入文件中
   * @param templateFile
   * @param params
   * @param outputFile
   * @return
   */
  boolean getExcel(String templateFile, Map 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 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 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 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 params = new HashMap();
    List 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 params = new HashMap();
    List 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内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • Imdevelopinganappwhichneedstogetmusicfilebystreamingforplayinglive.我正在开发一个应用程序,需要通过流 ... [详细]
  • HyperledgerComposer环境安装1.安装基本软件包**如果使用Linux安装HyperledgerComposer,请注意以下建议:以 ... [详细]
  • 打开文件管理器_【教程】模组管理器3.1食用指南
    文编:byakko最近有部分小伙伴反应还不会使用unity模组管理器,现在我就给大家讲一下unity模组管理器——从下载到使用。完整视频版以下是无WiF ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • MySQL5.6.40在CentOS764下安装过程 ... [详细]
  • 让你明白kvm是什么
    参考:https:blog.csdn.netbbwangjarticledetails80465320KVM工具集合:libvirt:操作和管理KVM虚机的虚拟化API ... [详细]
author-avatar
莫怀嘉805
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有