springboot+JXLS+Jexl实现报表模版生成报表

打印 上一主题 下一主题

主题 513|帖子 513|积分 1539

前言

做这个项目的思路是由于公司基于自身发展,需要将之前的老项目平台拆解出来,由于之前的项目是所有的功能全部集中在一起,学习成本以及后续的扩展性来说,非常的不友好,并且由于之前设计人员的流失导致了项目无法进一步优化,所以想将其进行拆解,将单个功能模块进行拆分,形成微服务化,使每个功能的业务更加单一,也更加简单
经过使用了一段时间的老平台,发现目前公司的平台的一些设计确实非常的好,其中,报表的设计理念比市面上大多的报表工具设计都要好,为什么呢,因为我们公司是基于B to B的项目模式,所以,客户可能会经常临时性的提出一些报表需求,并且需要响应时间比较快速,所以我们需要一种基于模版即可生成报表的报表工具
报表工具的比对

基于模版形式的报表工具

目前市场上基于模版的是JXLS,他的优势是JXLS 是基于 Jakarta POI API 的 Excel 报表生成工具,可以生成精美的 Excel 格式报表。它采用标签的方式,类似 JSP 标签,写一个 Excel 模板,然后生成报表,非常灵活,简单!
缺点是它只可以导出03版本的excel
实现jxls

配置与使用


  • 引入依赖
    1.                                 <dependency>
    2.             <groupId>org.jxls</groupId>
    3.             <artifactId>jxls</artifactId>
    4.             <version>2.8.0</version>
    5.         </dependency>
    6.         <dependency>
    7.             <groupId>org.jxls</groupId>
    8.             <artifactId>jxls-poi</artifactId>
    9.             <version>1.0.15</version>
    10.         </dependency>
    11.         <dependency>
    12.             <groupId>net.sf.jxls</groupId>
    13.             <artifactId>jxls-core</artifactId>
    14.             <version>1.0.5</version>
    15.         </dependency>
    复制代码
  • 编写工具辅助类
    研发一个execl生成的工具类,其中加入了自定义方法,这个思想与lims平台设计中的Alog类类似,采用Jexl来进行实现,本项目采用的是jexl3
    1. package com.thyc.reportserver.utils;
    2. import com.thyc.reportserver.excelCal.CalTime;
    3. import org.apache.commons.jexl3.JexlBuilder;
    4. import org.apache.commons.jexl3.JexlEngine;
    5. import org.jxls.area.Area;
    6. import org.jxls.builder.AreaBuilder;
    7. import org.jxls.builder.xls.XlsCommentAreaBuilder;
    8. import org.jxls.common.CellRef;
    9. import org.jxls.common.Context;
    10. import org.jxls.expression.JexlExpressionEvaluator;
    11. import org.jxls.transform.Transformer;
    12. import org.jxls.util.TransformerFactory;
    13. import javax.servlet.http.HttpServletResponse;
    14. import java.io.IOException;
    15. import java.io.InputStream;
    16. import java.io.OutputStream;
    17. import java.util.HashMap;
    18. import java.util.List;
    19. import java.util.Map;
    20. import java.util.Set;
    21. /**
    22. * @Description: excel辅助工具类
    23. * @Author: wanping
    24. * @Date: 6/13/23
    25. **/
    26. public class ExcelUtils {
    27.     /***
    28.      * excel导出到response
    29.      * @param fileName   导出文件名
    30.      * @param templateFile 模板文件地址
    31.      * @param params     数据集合
    32.      * @param response   response
    33.      */
    34.     public static void exportExcel(String fileName, InputStream templateFile, Map<String, Object> params,
    35.                                    HttpServletResponse response) throws IOException {
    36.         response.reset();
    37.         response.setHeader("Accept-Ranges", "bytes");
    38.         OutputStream os = null;
    39.         response.setHeader("Content-disposition", String.format("attachment; filename="%s"", fileName));
    40.         response.setContentType("application/octet-stream;charset=UTF-8");
    41.         try {
    42.             os = response.getOutputStream();
    43.             exportExcel(templateFile, params, os);
    44.         } catch (IOException e) {
    45.             throw e;
    46.         }
    47.     }
    48.     /**
    49.      * 导出excel到输出流中
    50.      * @param templateFile 模板文件
    51.      * @param params 传入参数
    52.      * @param os 输出流
    53.      * @throws IOException
    54.      */
    55.     public static void exportExcel(InputStream templateFile, Map<String, Object> params, OutputStream os) throws IOException {
    56.         try {
    57.             Context context = new Context();
    58.             Set<String> keySet = params.keySet();
    59.             for (String key : keySet) {
    60.                 //设置参数变量
    61.                 context.putVar(key, params.get(key));
    62.             }
    63.             Map<String, Object> myFunction = new HashMap<>();
    64.             myFunction.put("calTime", new CalTime());
    65.             // 启动新的jxls-api 加载自定义方法
    66.             Transformer trans = TransformerFactory.createTransformer(templateFile, os);
    67.             JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) trans.getTransformationConfig().getExpressionEvaluator();
    68. //            evaluator.getJexlEngine().setFunctions(myFunction); 这个方法是2版本的
    69.             JexlBuilder jb = new JexlBuilder();
    70.             jb.namespaces(myFunction);
    71.             JexlEngine je = jb.create();
    72.             evaluator.setJexlEngine(je);
    73.             // 载入模板、处理导出
    74.             AreaBuilder areaBuilder = new XlsCommentAreaBuilder(trans);
    75.             List<Area> areaList = areaBuilder.build();
    76.             areaList.get(0).applyAt(new CellRef("sheet1!A1"), context);
    77.             trans.write();
    78.         } catch (IOException e) {
    79.             throw e;
    80.         } finally {
    81.             try {
    82.                 if (os != null) {
    83.                     os.flush();
    84.                     os.close();
    85.                 }
    86.                 if (templateFile != null) {
    87.                     templateFile.close();
    88.                 }
    89.             } catch (IOException e) {
    90.                 throw e;
    91.             }
    92.         }
    93.     }
    94. }
    复制代码
  • 编写计算类
    1. package com.thyc.reportserver.excelCal;
    2. import org.jxls.transform.poi.WritableCellValue;
    3. import org.jxls.transform.poi.WritableHyperlink;
    4. import java.text.SimpleDateFormat;
    5. import java.util.Date;
    6. /**
    7. * @Description: excel计算时间方法
    8. * @Author: wanping
    9. * @Date: 6/13/23
    10. **/
    11. public class CalTime {
    12.     /**
    13.      * 格式化时间
    14.      */
    15.     public Object formatDate(Date date) {
    16.         if (date != null) {
    17.             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    18.             String dateStr = sdf.format(date);
    19.             return dateStr;
    20.         }
    21.         return "--";
    22.     }
    23.     /**
    24.      * 设置超链接方法
    25.      */
    26.     public WritableCellValue getLink(String address, String title) {
    27.         return new WritableHyperlink(address, title);
    28.     }
    29. }
    复制代码
  • 编写剩下的测试用例
    service
    1. package com.thyc.reportserver.service;
    2. import javax.servlet.http.HttpServletResponse;
    3. import java.io.File;
    4. import java.io.OutputStream;
    5. import java.util.Map;
    6. /**
    7. * @Description: TODO
    8. * @Author: wanping
    9. * @Date: 6/13/23
    10. **/
    11. public interface ExcelService {
    12.     /**
    13.      * 导出excel,写入文件中
    14.      * @param templateFile
    15.      * @param params
    16.      * @param outputFile
    17.      * @return
    18.      */
    19.     boolean getExcel(String templateFile, Map<String,Object> params, File outputFile);
    20. }
    复制代码
    impl
    1. package com.thyc.reportserver.service.impl;
    2. import com.thyc.reportserver.service.ExcelService;
    3. import com.thyc.reportserver.utils.ExcelUtils;
    4. import javax.servlet.http.HttpServletResponse;
    5. import org.slf4j.Logger;
    6. import org.slf4j.LoggerFactory;
    7. import org.springframework.beans.factory.annotation.Value;
    8. import org.springframework.stereotype.Service;
    9. import org.springframework.util.ResourceUtils;
    10. import java.io.*;
    11. import java.util.Map;
    12. /**
    13. * @Description: TODO
    14. * @Author: wanping
    15. * @Date: 6/13/23
    16. **/
    17. @Service
    18. public class ExcelServiceImpl implements ExcelService {
    19.     private Logger logger = LoggerFactory.getLogger(getClass());
    20.     /**
    21.      * 模板文件的基础路径
    22.      */
    23.     @Value("${jxls.template.path}")
    24.     private String templatePath;
    25.     @Override
    26.     public boolean getExcel(String templateFile, Map<String, Object> params, File outputFile) {
    27.         FileInputStream inputStream = null;
    28.         try {
    29.             //获取模板文件的输入流
    30.             inputStream = new FileInputStream(ResourceUtils.getFile(templatePath + templateFile));
    31.             File dFile = outputFile.getParentFile();
    32.             //文件夹不存在时创建文件夹
    33.             if(dFile.isDirectory()){
    34.                 if(!dFile.exists()){
    35.                     dFile.mkdir();
    36.                 }
    37.             }
    38.             //文件不存在时创建文件
    39.             if(!outputFile.exists()){
    40.                 outputFile.createNewFile();
    41.             }
    42.             //导出excel文件
    43.             ExcelUtils.exportExcel(inputStream, params, new FileOutputStream(outputFile));
    44.         } catch (IOException e) {
    45.             logger.error("excel export has error" + e);
    46.             return false;
    47.         }
    48.         return true;
    49.     }
    50. }
    复制代码
    编写测试用例
    1. package com.thyc.reportserver;
    2. import com.thyc.reportserver.excelModel.UserModel;
    3. import com.thyc.reportserver.service.ExcelService;
    4. import org.junit.jupiter.api.Test;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. import java.io.File;
    8. import java.util.*;
    9. @SpringBootTest
    10. class ReportServerApplicationTests {
    11.     @Autowired
    12.     ExcelService excelService;
    13.     @Test
    14.     void contextLoads() {
    15.         Map<String, Object> params = new HashMap();
    16.         List<UserModel> list = new ArrayList<>();
    17.         for (int i = 0; i < 10; i++) {
    18.             int i1 = i + 1;
    19.             list.add(new UserModel(i1, "test" + i1, "男", 25 + i, "tttttttttt" + i1, new Date(), "htpp://wwww.baidu.com"));
    20.         }
    21.         params.put("list", list);
    22.         excelService.getExcel("user1.xlsx", params, new File("/Users/wanping/IdeaProjects/ddd/report-server/excel/test01.xlsx"));
    23.     }
    24. }
    复制代码

    • 结果展示
    导入模版


结果

参考:https://www.jb51.net/article/195015.htm

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

何小豆儿在此

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表