• JXLS (Excel导入、导出工具使用)


    JXLS (Excel导入、导出工具使用)

    1:简介:

           jxls是一个简单的、轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局。java中成熟的excel导出工具有pol、jxl,但他们都是使用java代码的方式来导出excel,编码效率很低且不方便维护。

    还可以使用一些工具很轻松的实现模板导出。这些工具现在还在维护,而且做得比较好的国内的有easyPOI,国外的就是这个JXLS了。

    比较:

    项目中有很多复杂的报表(大量单元格合并和单元格样式),easyPOI处理合并单元格时候容易出现残损的情况,poi代码维护成本高。

    2:maven依赖:

    <dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls</artifactId>
    <version>[2.6.0-SNAPSHOT,)</version>
    </dependency>
    <dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-poi</artifactId>
    <version>[1.2.0-SNAPSHOT,)</version>
    </dependency>
    <dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-jexcel</artifactId>
    <version>[1.0.8,)</version>
    </dependency>
    <dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-reader</artifactId>
    <version>[2.0.5,)</version>
    </dependency>

    2:下面先做一个简单导出的实现:

    1: 创建model:

     2:先用office创建一个xlsx的模板

     

    可以看到这里有一些cell 的文本批注,office中添加批注快捷键(Shit + F2),批注中的类容这里先不做解释,下面会讲到

    3:工具类JxlsUtils.java

    public class JxlsUtils{
         
        private static final String TEMPLATE_PATH="jxls-template";
         
        public static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException{
            Context context = new Context();
            if (model != null) {
                for (String key : model.keySet()) {
                    context.putVar(key, model.get(key));
                }
            }
            JxlsHelper jxlsHelper = JxlsHelper.getInstance();
            Transformer transformer  = jxlsHelper.createTransformer(is, os);
            JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
            Map<String, Object> funcs = new HashMap<String, Object>();
          //  funcs.put("utils", new JxlsUtils());    //添加自定义功能
          //  evaluator.getJexlEngine().setFunctions(funcs);
            jxlsHelper.processTemplate(context, transformer);
        }
     
        public static void exportExcel(File xls, File out, Map<String, Object> model) throws FileNotFoundException, IOException {
                exportExcel(new FileInputStream(xls), new FileOutputStream(out), model);
        }
         
        public static void exportExcel(String templateName, OutputStream os, Map<String, Object> model) throws FileNotFoundException, IOException {
            File template = getTemplate(templateName);
            if(template!=null){
                exportExcel(new FileInputStream(template), os, model);    
            }
        }
         
         
        //获取jxls模版文件
     
        public static File getTemplate(String name){
            String templatePath = JxlsUtils.class.getClassLoader().getResource(TEMPLATE_PATH).getPath();
            File template = new File(templatePath, name);
            if(template.exists()){
                return template;
            }
            return null;
        }    
         
        // 日期格式化
        public String dateFmt(Date date, String fmt) {
            if (date == null) {
                return "";
            }
            try {
                SimpleDateFormat dateFmt = new SimpleDateFormat(fmt);
                return dateFmt.format(date);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
         
        // if判断
        public Object ifelse(boolean b, Object o1, Object o2) {
            return b ? o1 : o2;
        }
         
    }

    上面注释中的自定义功能可以先注释到,我们后面在讲

    入口ObjectCollectionDemo.java

    public class ObjectCollectionDemo {
        static Logger logger = LoggerFactory.getLogger(ObjectCollectionDemo.class);
         
        public static void main(String[] args) throws ParseException, IOException {
            logger.info("Running Object Collection demo");
             
            List<Employee> employees = generateSampleEmployeeData();
            OutputStream os = new FileOutputStream("target/object_collection_output.xls");
            Map<String , Object> model=new HashMap<String , Object>();
            model.put("employees", employees);
            model.put("nowdate", new Date());
            JxlsUtils.exportExcel("object_collection_template.xls", os, model);
            os.close();
        }
     
        public static List<Employee> generateSampleEmployeeData() throws ParseException {
            List<Employee> employees = new ArrayList<Employee>();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-dd", Locale.US);
            employees.add( new Employee("Elsa", dateFormat.parse("1970-Jul-10"), 1500, 0.15) );
            employees.add( new Employee("Oleg", dateFormat.parse("1973-Apr-30"), 2300, 0.25) );
            employees.add( new Employee("Neil", dateFormat.parse("1975-Oct-05"), 2500, 0.00) );
            employees.add( new Employee("Maria", dateFormat.parse("1978-Jan-07"), 1700, 0.15) );
            employees.add( new Employee("John", dateFormat.parse("1969-May-30"), 2800, 0.20) );
            return employees;
        }
    }

    生成效果:

     好的,这样就很轻松的导出了是不是很简单


    3:下面讲一下导出的细节,注意事项:

    1:模板中的批注:

    注意如果模板中对单元格加了批注,但是没有批注信息的话可能会报错:

     1-1:bean属性标记

    jxls使用 Apache JEXL表达式语言来解析定义在excel模板中的表达式。JEXL与JSTL相似,并对JSTL进行了扩展。eg:

    ${department.chief.age} //属性可以是无限深度

    ${utils:dateFmt(date,"yyyy-MM-dd")} //自定义工具函数

    1-2:XLS Area定义标记

    XLS Area 是JxlsPlus中的一个重要概念,它代表excel模板中需要被解析的矩形区域,由A1到最后一个单元格表示,有利于加快解析速度。

    XLS Area 使用excel注释标注表示,它需要被定义在excel 模板的第一个单元格(A1):

    jx:area(lastCell = "<AREA_LAST_CELL>")

    1-3:XLS Command表示标记

    XLS Command 使用excel注释标注表示,命令格式如下:

    jx:<command_name>(attr1='val1' attr2='val2' ... attrN='valN' lastCell=<last_cell> areas=["<command_area1>", "<command_area2", 
    ... "<command_areaN>"])

    <command_name> 是库自带的命名或是用户自定义并注册到XlsCommentAreaBuilder的命令。

    each 命令是最常用的XLS命令,形如:

    jx:each(items="employees" var="employee" lastCell="D4")

    eg:

    each 可以有如下一些属性:

    • items 上下文中集合的变量名;
    • var 在遍历集合的时候每一条记录的变量名;
    • area 该XLS Command的解析区域;
    • direction 数据在excel中填充的方向,默认(DOWN)向下;
    • select 其值为一个表达式,用来过滤数据

     横向遍历显示list的数据:

     jx:each(items="data" var="dat" lastCell="A3" direction="RIGHT")

     1-4:jexl自定义工具函数:

    如果你需要自定jexl来处理数据,你可以从Transformer对象获取JexlEngine引用,并对其配置。

    下面的例子实现了将一个自定义jexl函数注册到utils命名空间下:

    JxlsHelper jxlsHelper = JxlsHelper.getInstance();
    Transformer transformer = jxlsHelper.createTransformer(is, os);
    JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
    Map<String, Object> funcs = new HashMap<String, Object>();
    funcs.put("utils", new JxlsUtils()); //添加自定义功能
    evaluator.getJexlEngine().setFunctions(funcs);

     1-5:单元格合并命令:

    Excel注释语法

    jx:merge(
    lastCell =“合并单元格范围” 
    [,cols =“合并的列数”] 
    [,rows =“合并的行数”] 
    [,minCols =“要合并的最小列数”] 
    [,minRows = “要合并的最小行数”] 
    )

    注意:此命令只能用于尚未合并的单元格。如果合并单元格的合并单元格范围存在,则会发生异常。

    官方文档:http://jxls.sourceforge.net/reference/excel_markup.html

    官方文档打不开?下个加速器就可以了:http://www.youxia66.com/

    参考博客:https://www.cnblogs.com/klguang/p/6425422.html

    博客源码:

    demo工程源码下载http://files.cnblogs.com/files/klguang/jxlsdemo.zip

  • 相关阅读:
    SQL基础 union的用法
    VSCore的使用方法
    k8s——了解kubernetes机理
    电子科大啦
    19款程序员最爱的开发框架
    Exp1 PC平台逆向破解(5)M
    电子阅读
    Python学习记录:基础知识1
    WCF使用小结:(1)WCF接收HTTP POST数据的处理方法
    Linux配置经验总结:(3)禁用笔记本触摸屏
  • 原文地址:https://www.cnblogs.com/dw3306/p/11098841.html
Copyright © 2020-2023  润新知