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.4和2.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)),要不后续文章中会写到怎么做excel分sheet输出,如果不设置成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好像没有这个问题了,不太确定。

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

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

  

  最后说明一下:

  1.jxls会自动根据你model中put的值来判断写入进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系列教程(一)——最简单的模板导出的更多相关文章

  1. JXLS 2.4.0系列教程(二)——循环导出一个链表的数据

    请务必先看上一篇文章,本文在上一篇文章的代码基础上修改而成. JXLS 2.4.0系列教程(一)--最简单的模板导出 上一篇文章我们介绍了JXLS和模板导出最简单的应用,现在我们要更进一步,介绍在模板 ...

  2. JXLS 2.4.0系列教程(五)——更进一步的应用和页面边距bug修复

    注:本文代码建立于前面写的代码.不过不看也不要紧. 前面的文章把JXLS 2.4.0 的基本使用写了一遍,现在讲讲一些更进一步的使用方法.我只写一些我用到过的方法,更多的高级使用方法请参考官网. ht ...

  3. JXLS 2.4.0系列教程(四)——多sheet是怎么做到的

    注:本文代码在第一篇文章基础上修改而成,请务必先阅读第一篇文章. http://www.cnblogs.com/foxlee1024/p/7616987.html 本文也不会过多的讲解模板中遍历表达式 ...

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

    突然想起来有同学说过能不能导出图片,本来我是想说不懂的,后来我上官网查了查,还挺容易.我就简短的写一写怎么导出图片. 官方提供了导出图片标签: jx:image(lastCell="D10& ...

  5. JXLS 2.4.0系列教程(四)——拾遗 如何做页面小计

    注:阅读本文前,请先阅读第四篇文章. http://www.cnblogs.com/foxlee1024/p/7619845.html 前面写了第四篇教程,发现有些东西忘了讲了,这里补回来. 忘了讲两 ...

  6. JXLS 2.4.0系列教程(三)——嵌套循环是怎么做到的

    注:本文代码在第一篇文章基础上修改而成,请务必先阅读第一篇文章. http://www.cnblogs.com/foxlee1024/p/7616987.html 本文也不会过多的讲解模板中遍历表达式 ...

  7. Enterprise Library 5.0 系列教程

    1. Microsoft Enterprise Library 5.0 系列教程(一) Caching Application Block (初级) 2. Microsoft Enterprise L ...

  8. 黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block 开发人员经常编写需要安全功能的应用程序.这些应用程序 ...

  9. 黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block 使用企业库异常处理应用程序模块的 ...

随机推荐

  1. [置顶] bootstrap自定义样式-bootstrap侧边导航栏的实现

    前言 bootstrap自带的响应式导航栏是向下滑动的,有时满足不了个性化的需求,需要做一个类似于android drawerLayout 侧滑的菜单,这就是我要实现的bootstrap自定义侧滑菜单 ...

  2. Windows as a Service(4)——使用Intune管理Windows10更新

    这是这个系列的最后一篇文章,我已经花了三篇的篇幅和大家分享有关于Windows as a Serivce的相关内容,链接如下: Windows as a Service(1)-- Windows 10 ...

  3. 学习 Kubernetes 的 Why 和 How - 每天5分钟玩转 Docker 容器技术(114)

    这是一个系统学习 Kubernetes 的教程,有下面两个特点: 系统讲解当前最流行的容器编排引擎 Kubernetes包括了安装部署.应用管理.网络.存储.监控.日志管理等多各个方面. 重实践并兼顾 ...

  4. userdel 命令详解

    userdel  作用: 删除指定用户,以及用户相关的文件. 如不加选项,则仅删除用户账号,而不删除相关文件 选项: -f:强制删除用户,即时用户当前已登录 -r:删除用户的同时删除与用户相关的所有文 ...

  5. (一)初识mybatis

    Mybatis 是现在很多公司都选择使用的一个ORM(Object Relational Mapping)框架,所以是值得了解和学习一番的. MyBatis 是支持定制化 SQL.存储过程以及高级映射 ...

  6. spring中使用Hibernate中的getCurrentSession报出:createQuery is not valid without active transaction

    1.错误信息 HTTP Status 500 - createQuery is not valid without active transaction type Exception report m ...

  7. Nginx集群及代理的应用

    目录 1       大概思路... 1 2       了解Nginx及文档资源... 1 3       Nginx命令模块及进程结构... 2 4       解读Nginx配置... 3 5  ...

  8. [SharePoint]解决用户权限被无缘无故自动删除的问题

    前几天在维护公司内网的时候接到了一个case, 说是某个用户的权限无缘无故的就会被SharePoint自动去掉. 刚开始我还不愿意相信这个用户的说法,认为可能是权限赋的方法不对,有可能是被其他人误删了 ...

  9. Java编程思想读书笔记(一)【对象导论】

    2018年1月7日15:45:58 前言 作为学习Java语言的经典之作<Java编程思想>,常常被人提起.虽然这本书出版十年有余,但是内容还是很给力的.很多人说这本书不是很适合初学者,我 ...

  10. iOS学习——获取iOS设备的各种信息

    不管是在Android开发还是iOS开发过程中,有时候我们需要经常根据设备的一些状态或信息进行不同的设置和性能配置,例如横竖屏切换时,电池电量低时,内存不够时,网络切换时等等,我们在这时候需要进行一些 ...