首页 > 其他 > 详细

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

时间:2017-10-01 12:54:07      阅读:1255      评论:0      收藏:0      [点我收藏+]

Java中实现excel根据模板导出数据的方法有很多,一般简单的可以通过操作POI进行。还可以使用一些jar包很轻松的实现模板导出。这些jar包现在还在维护,而且做得比较好的国内的有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系列教程(一)——最简单的模板导出

原文:http://www.cnblogs.com/foxlee1024/p/7616987.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!