首页 > 其他分享 >springboot+JXLS+Jexl实现报表模版生成报表

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

时间:2023-06-13 18:33:05浏览次数:57  
标签:java 报表 jxls new JXLS Jexl params org import

前言

做这个项目的思路是由于公司基于自身发展,需要将之前的老项目平台拆解出来,由于之前的项目是所有的功能全部集中在一起,学习成本以及后续的扩展性来说,非常的不友好,并且由于之前设计人员的流失导致了项目无法进一步优化,所以想将其进行拆解,将单个功能模块进行拆分,形成微服务化,使每个功能的业务更加单一,也更加简单

经过使用了一段时间的老平台,发现目前公司的平台的一些设计确实非常的好,其中,报表的设计理念比市面上大多的报表工具设计都要好,为什么呢,因为我们公司是基于B to B的项目模式,所以,客户可能会经常临时性的提出一些报表需求,并且需要响应时间比较快速,所以我们需要一种基于模版即可生成报表的报表工具

报表工具的比对

基于模版形式的报表工具

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

缺点是它只可以导出03版本的excel

实现jxls

配置与使用
  1. 引入依赖

    				<dependency>
                <groupId>org.jxls</groupId>
                <artifactId>jxls</artifactId>
                <version>2.8.0</version>
            </dependency>
            <dependency>
                <groupId>org.jxls</groupId>
                <artifactId>jxls-poi</artifactId>
                <version>1.0.15</version>
            </dependency>
            <dependency>
                <groupId>net.sf.jxls</groupId>
                <artifactId>jxls-core</artifactId>
                <version>1.0.5</version>
            </dependency>
    
  2. 编写工具辅助类

    研发一个execl生成的工具类,其中加入了自定义方法,这个思想与lims平台设计中的Alog类类似,采用Jexl来进行实现,本项目采用的是jexl3

    package com.thyc.reportserver.utils;
    
    import com.thyc.reportserver.excelCal.CalTime;
    import org.apache.commons.jexl3.JexlBuilder;
    import org.apache.commons.jexl3.JexlEngine;
    import org.jxls.area.Area;
    import org.jxls.builder.AreaBuilder;
    import org.jxls.builder.xls.XlsCommentAreaBuilder;
    import org.jxls.common.CellRef;
    import org.jxls.common.Context;
    import org.jxls.expression.JexlExpressionEvaluator;
    import org.jxls.transform.Transformer;
    import org.jxls.util.TransformerFactory;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * @Description: excel辅助工具类
     * @Author: wanping
     * @Date: 6/13/23
     **/
    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("calTime", new CalTime());
                // 启动新的jxls-api 加载自定义方法
                Transformer trans = TransformerFactory.createTransformer(templateFile, os);
                JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) trans.getTransformationConfig().getExpressionEvaluator();
    //            evaluator.getJexlEngine().setFunctions(myFunction); 这个方法是2版本的
                JexlBuilder jb = new JexlBuilder();
                jb.namespaces(myFunction);
                JexlEngine je = jb.create();
                evaluator.setJexlEngine(je);
    
                // 载入模板、处理导出
                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;
                }
            }
        }
    }
    
    
  3. 编写计算类

    package com.thyc.reportserver.excelCal;
    
    import org.jxls.transform.poi.WritableCellValue;
    import org.jxls.transform.poi.WritableHyperlink;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @Description: excel计算时间方法
     * @Author: wanping
     * @Date: 6/13/23
     **/
    public class CalTime {
    
        /**
         * 格式化时间
         */
        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);
        }
    
    }
    
  4. 编写剩下的测试用例

    service

    package com.thyc.reportserver.service;
    
    import javax.servlet.http.HttpServletResponse;
    
    import java.io.File;
    import java.io.OutputStream;
    import java.util.Map;
    
    /**
     * @Description: TODO
     * @Author: wanping
     * @Date: 6/13/23
     **/
    public interface ExcelService {
    
        /**
         * 导出excel,写入文件中
         * @param templateFile
         * @param params
         * @param outputFile
         * @return
         */
        boolean getExcel(String templateFile, Map<String,Object> params, File outputFile);
    }
    
    

    impl

    package com.thyc.reportserver.service.impl;
    
    import com.thyc.reportserver.service.ExcelService;
    import com.thyc.reportserver.utils.ExcelUtils;
    import javax.servlet.http.HttpServletResponse;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    import org.springframework.util.ResourceUtils;
    
    import java.io.*;
    import java.util.Map;
    
    /**
     * @Description: TODO
     * @Author: wanping
     * @Date: 6/13/23
     **/
    @Service
    public class ExcelServiceImpl implements ExcelService {
    
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        /**
         * 模板文件的基础路径
         */
        @Value("${jxls.template.path}")
        private String templatePath;
    
        @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;
        }
    }
    
    

    编写测试用例

    package com.thyc.reportserver;
    
    import com.thyc.reportserver.excelModel.UserModel;
    import com.thyc.reportserver.service.ExcelService;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.File;
    import java.util.*;
    
    @SpringBootTest
    class ReportServerApplicationTests {
    
        @Autowired
        ExcelService excelService;
    
        @Test
        void contextLoads() {
            Map<String, Object> params = new HashMap();
            List<UserModel> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                int i1 = i + 1;
                list.add(new UserModel(i1, "test" + i1, "男", 25 + i, "tttttttttt" + i1, new Date(), "htpp://wwww.baidu.com"));
            }
            params.put("list", list);
            excelService.getExcel("user1.xlsx", params, new File("/Users/wanping/IdeaProjects/ddd/report-server/excel/test01.xlsx"));
        }
    
    }
    
    1. 结果展示

    导入模版

结果

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

标签:java,报表,jxls,new,JXLS,Jexl,params,org,import
From: https://www.cnblogs.com/java5wanping/p/17478450.html

相关文章

  • 轻量级报表解决方案Telerik Reporting,轻松完成嵌入式报表交互!
    开发者可以通过多种方式与集成在应用程序中的Telerik报表进行交互,从“只是阅读它”到更改报表中包含的数据。但是要注意:开发者所能做的一些事情将取决于报表是如何创建的,以及它是如何嵌入到应用程序UI中的。因此(和任何应用程序一样),为了从Telerik报表中获得想要的,开发团队尽量要......
  • 在线报表怎么做?有没有好用的在线报表工具?
    随着企业数据的不断增长,数据分析和可视化已经成为了企业决策的重要手段。而在线报表则是其中的一个重要工具。本文将介绍如何制作在线报表以及几个好用的在线报表工具。一、在线报表的制作步骤制作在线报表需要经过以下步骤:收集数据:收集所需的数据,并对其进行清理和整理,确保数据的准......
  • 热门自定义报表系统推荐,哪款自定义报表系统更功能更强大?
    随着企业管理的日益复杂,越来越多的企业需要一款高效、灵活、易用的自定义报表系统来满足其各种报表制作和数据分析需求。然而,在众多自定义报表系统中,哪款更加强大?今天,我将向大家推荐5款热门自定义报表系统,并详细介绍其中最具代表性的VeryReport自定义报表系统。1.VeryReport编辑搜......
  • 报表制作很复杂?用了这款报表制作工具轻松完成报表制作
    在企业管理中,报表是非常重要的一环。然而,很多人对于报表制作却感到十分困难和繁琐。事实上,报表制作并不需要太高深的技能,只要掌握了一些基本的操作技巧和使用工具,就可以轻松地完成报表制作。而VeryReport报表制作工具则是一款非常适合初学者使用的报表制作软件。编辑搜图请点击输入......
  • 揭秘报表新玩法!标配插件不再单调,如何用柱形图插件让你的报表瞬间高大上!
    摘要:本文由葡萄城技术团队于博客园原创并首发。葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。前言图表作为一款用于可视化数据的工具,可以帮助我们更好的分析和理解数据,并发现数据之间的关系和趋势。下面以柱形图为例介绍如何使用JavaScript在报表中引入图表......
  • 看看Angular有啥新玩法!手把手教你在Angular15中集成Excel报表插件
    Angular15新特性Angular框架(以下简称“Angular”)作为一款由谷歌开发的Web应用程序框架,其强大的依赖注入系统、可重复使用的模块化开发理念和响应式编程模式等特点让Angular一问世便取得了巨大的关注和流量。截止目前为止,Angular已经迭代了15个版本,而Angular15又有哪些新的亮眼表现......
  • 可视化报表系统推荐
    在当今信息时代,数据的处理和分析已经成为了企业管理中不可或缺的一部分。而报表则是这个过程中最常见的工具之一。手工写报表虽然简单易懂,但是随着数据量的增加,这种方式逐渐暴露出许多痛点。比如说:1.时间耗费长:手工写报表需要大量的人力物力,花费时间长,容易出错。2.精度低:手工计算很......
  • 瓴羊Quick BI报表分析工具,大幅提升企业经营效率
    随着ChatGPT等大模型软件的迅速崛起,在工作中使用智能工具提高效率、节省人力成了许多企业共同的选择。从目前的应用场景看,ChatGPT等软件大多是基于自然语言处理技术的生成式人工智能模型,更善于处理文字、图片类的工作,对于企业经营过程中海量业务数据的处理,更依靠瓴羊QuickBI报表分......
  • 选择 BI 报表工具的五大要素
    商业智能(BI)市场上有很多的BI报表工具,为您的企业选择一款合适的工具变得非常关键,选择不当通常会导致最终转向重新选择,白白浪费了金钱,增加了成本,导致花费了两倍的时间和精力。因此,评估和选择正确的工具非常重要。皕杰信息自2007年以来一直专注报表工具领域,基于自身十多年的经验及众......
  • 如何把一个报表从2分钟优化到1秒?---GaussDB数据库
    报表优化系列文章----如何把一个报表从2分钟优化到1秒?优化需求:报表名:外部数据查询报表\EDM004-外部数据查询量业务类型_部门编号需求说明:原报表SQL运行时长2分钟,感觉慢,让DBA看看是否有优化的空间,给优化一下。优化人:4K/weicat:wx120890945优化日期:2022-03-03数据库类型:Ga......