JXLS 2.4.0系列教程——最简单的模板导出

Posted 李狐同学的异世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JXLS 2.4.0系列教程——最简单的模板导出相关的知识,希望对你有一定的参考价值。

  Java中实现excel根据模板导出数据的方法有很多,一般简单的可以通过操作POI进行。还可以使用一些工具很轻松的实现模板导出。这些工具现在还在维护,而且做得比较好的国内的有easyPOI,国外的就是这个JXLS了。

  笔者使用jxls 2也有半年的时间了,半年前因项目原因需要导出大量的excel文件,所以找到了jxls2,这是目前我用过最好的excel导出工具,基本可以完全满足所有的项目需要。不使用easypoi的原因是那时候测试时候效果不是很好,项目中有很多复杂的报表(大量单元格合并和单元格样式),easyPOI处理合并单元格时候容易出现残损的情况。

  今天我们着重介绍一下JXLS 2.4.0 ,写文章前我搜索了下JXLS的教程,发现半年前我看到的是什么文章,现在的还是什么文章,大量的文章停留在JXLS1.0时代(作者2.0后重写了代码,使用方法完全不同)。唯一最新的一篇中文文章是klguang 写的《jxls2.3-简明教程》。剩下的就是官方文档了。其实官方文档也很不错,就是系统化不够,值此国庆之际,正好把我的工作中使用JXLS的经验写一下,让更多人接触这款优秀的工具。

  首先,我推荐各位有能力的先上官网下载最新版本和了解下基础功能。(有没有被墙看缘分,公司的电信网络可以直接上,家里联通的要挂VPN

http://jxls.sourceforge.net/index.html

  其次,推荐各位完整的看完klguang 大神写的《jxls2.3-简明教程》这篇文章。里面提供了klguang 大神的工具类,本文也基于他的工具类进行介绍(部分代码进行修改)。

http://www.cnblogs.com/klguang/p/6425422.html

 

  好,现在我们开始。

  我这里使用jxls 2.4.0进行教程(不使用最新的2.4.2是因为我懒,教程用的jar包是我直接从公司项目拷的,懒得去测试新版本会不会有什么幺蛾子,不过我看了下更新说明,只是修复了一个bug,应该问题不大)。2.42.3在操作上没什么变化,但是在jar包的依赖上发生了变化,所以在使用2.4时候主要看我提供需要依赖的jar包文件。

 

  除了官方需要的jar包外,还需要加入几个依赖的包(都是必须的,少一个就报错)。文章后我给出依赖包的下载地址。用Maven的朋友我就不说怎么引包了,写上就自动下载依赖了。

接下来,我们在项目中复制util工具类:

package com.test.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;

/**
 * @author klguang
 */
public class JxlsUtils{
    
    public static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException{
        Context context = PoiTransformer.createInitialContext();
        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();
        //设置静默模式,不报警告
        //evaluator.getJexlEngine().setSilent(true);
        //函数强制,自定义功能
        Map<String, Object> funcs = new HashMap<String, Object>();
        funcs.put("utils", new JxlsUtils());    //添加自定义功能
        evaluator.getJexlEngine().setFunctions(funcs);
        //必须要这个,否者表格函数统计会错乱
        jxlsHelper.setUseFastFormulaProcessor(false).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 templatePath, OutputStream os, Map<String, Object> model) throws Exception {
        File template = getTemplate(templatePath);
        if(template != null){
            exportExcel(new FileInputStream(template), os, model);    
        } else {
            throw new Exception("Excel 模板未找到。");
        }
    }
    
    //获取jxls模版文件
    public static File getTemplate(String path){
        File template = new File(path);
        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;
    }
}

  我在klguang 的基础上略作了修改,有两点需要讲一下:

  1.静默模式是在导出excel模板时候,如果模板中标签名没有在传入的map中找到数值,会打印报告某某某标签没有赋值。如果开启静默模式后则不会报告。放心,出现严重异常还是会报错的。

  2.函数统计错乱,这个必须设置(setUseFastFormulaProcessor(false)),要不后续文章中会写到怎么做excelsheet输出,如果不设置成false,以后用excel自带函数统计相加会加错地方。

 

  工欲善其事必先利其器,接着我们可以写一个Main方法了。

public class TestMain {
    public static void main(String[] args) throws Exception {
        // 模板路径和输出流
        String templatePath = "E:/template.xls";
        OutputStream os = new FileOutputStream("E:/out.xls");
        // 定义一个Map,往里面放入要在模板中显示数据
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("id", "001");
        model.put("name", "张三");
        model.put("age", 18);
        //调用之前写的工具类,传入模板路径,输出流,和装有数据Map
        JxlsUtils.exportExcel(templatePath, os, model);
        os.close();
        System.out.println("完成");
    }
}

  

  就这么简单,接下来我们做事写模板。

  在E盘建立一个名字叫template.xls的文件,然后在里面加入以下的内容。

  如果你前面看了klguang的教程,你应该知道里面的注释是什么意思。不过我还是简单讲一下:

  第一步,在报表中最左上角(A1)加入一个注释jx:area(lastCell="D3"),含义为模板的区域由A1(加注释的单元格)到D3。有一点说明:

  区域最好比你设计的模板大一圈就是你的模板内容只到C2,而你要设置区域到D3。理由是在2.3版本中lastCell的值如果在有表达式的单元格或者在合并后的单元格,容易报空指针异常,2.4好像没有这个问题了,不太确定。

  第二步,在你设定的模板区域内写入表达式${ },表达式中写入前面modelput的“键”。

 

  好了,模板写完,保存,执行java代码,我们就可以看到效果了:

 

  

  最后说明一下:

  1.jxls会自动根据你modelput的值来判断写入进excel中的是字符串还是数值。

  2.A1单元格这个被注释使用的单元格也是可以写表达式的。

  3.如果你在模板中写了一个model 中找不到对应键的表达式,比如我在A3中写${aaaa},再运行代码,则会报提示:

警告: org.jxls.expression.JexlExpressionEvaluator.evaluate@61![0,4]: \'aaaa;\' undefined variable aaaa

  如果不想要提示就在JxlsUtils类中设置静默模式:evaluator.getJexlEngine().setSilent(true);

 

  jar包下载地址(内有官方2.4.0版本,2.4依赖的jar包,klguang 的demo)这里下载

 

  接下来我计划写四篇文章,仔细的描述我使用jxls的一些技巧。JXLS是一个很强大的excel操作工具,可以导入导出,模板导出,代码导出,xml导出,导出显示图片,连接数据库等等功能。具体的功能有需要的同学请上官网查询。我只写一些我用到过的功能。

  我附上我计划写的文章的大纲,有需要的同学敬请期待,预计2017年国庆内写完。

最简单应用
需要的包
标签介绍,类介绍
直接输出

循环
容易出现的报错
简单循环,标签介绍

分sheet
如何分sheet

循环嵌套
如何嵌套

高级应用,和bug修复
map
统计
使用工具
静默模式
边距bug

 

 

 

以上是关于JXLS 2.4.0系列教程——最简单的模板导出的主要内容,如果未能解决你的问题,请参考以下文章

JXLS 2.4.0系列教程番外篇——导出图片(完结)

JXLS 2.4.0系列教程——拾遗 如何做页面小计

JXLS 2.4.0系列教程——嵌套循环是怎么做到的

JXLS 2.4.0系列教程——多sheet是怎么做到的

JXLS 2.4.0系列教程——更进一步的应用和bug修复

请问你用jxls 导出2007格式的Excel搞定了没有?求解决方案