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系列教程(一)——最简单的模板导出的更多相关文章
-
JXLS 2.4.0系列教程(二)——循环导出一个链表的数据
请务必先看上一篇文章,本文在上一篇文章的代码基础上修改而成. JXLS 2.4.0系列教程(一)--最简单的模板导出 上一篇文章我们介绍了JXLS和模板导出最简单的应用,现在我们要更进一步,介绍在模板 ...
-
JXLS 2.4.0系列教程(五)——更进一步的应用和页面边距bug修复
注:本文代码建立于前面写的代码.不过不看也不要紧. 前面的文章把JXLS 2.4.0 的基本使用写了一遍,现在讲讲一些更进一步的使用方法.我只写一些我用到过的方法,更多的高级使用方法请参考官网. ht ...
-
JXLS 2.4.0系列教程(四)——多sheet是怎么做到的
注:本文代码在第一篇文章基础上修改而成,请务必先阅读第一篇文章. http://www.cnblogs.com/foxlee1024/p/7616987.html 本文也不会过多的讲解模板中遍历表达式 ...
-
JXLS 2.4.0系列教程(六)番外篇——导出图片(完结)
突然想起来有同学说过能不能导出图片,本来我是想说不懂的,后来我上官网查了查,还挺容易.我就简短的写一写怎么导出图片. 官方提供了导出图片标签: jx:image(lastCell="D10& ...
-
JXLS 2.4.0系列教程(四)——拾遗 如何做页面小计
注:阅读本文前,请先阅读第四篇文章. http://www.cnblogs.com/foxlee1024/p/7619845.html 前面写了第四篇教程,发现有些东西忘了讲了,这里补回来. 忘了讲两 ...
-
JXLS 2.4.0系列教程(三)——嵌套循环是怎么做到的
注:本文代码在第一篇文章基础上修改而成,请务必先阅读第一篇文章. http://www.cnblogs.com/foxlee1024/p/7616987.html 本文也不会过多的讲解模板中遍历表达式 ...
-
Enterprise Library 5.0 系列教程
1. Microsoft Enterprise Library 5.0 系列教程(一) Caching Application Block (初级) 2. Microsoft Enterprise L ...
-
黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block 开发人员经常编写需要安全功能的应用程序.这些应用程序 ...
-
黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block 使用企业库异常处理应用程序模块的 ...
随机推荐
-
freeCodeCamp:Caesars Cipher
让上帝的归上帝,凯撒的归凯撒. 下面我们来介绍风靡全球的凯撒密码Caesar cipher,又叫移位密码. 移位密码也就是密码中的字母会按照指定的数量来做移位. 一个常见的案例就是ROT13密码,字母 ...
-
Codeforces Round #270
A 题意:给出一个数n,求满足a+b=n,且a+b均为合数的a,b 方法一:可以直接枚举i,n-i,判断a,n-i是否为合数 #include<iostream> #include< ...
-
Python脚本控制的WebDriver 常用操作 <;二十一>; 执行JS
测试用例场景 如果你熟悉js的话,那么使用webdriver执行js就是一件很高效的事情了.在webdriver脚本中直接执行js的好处很多,这里就不一一枚举了. webdriver提供了execut ...
-
巧妙地使用typora编辑有道云笔记
设置方法 找到有道云笔记本地保存路径: 找到有道云笔记的保存的路径:启动有道云 - 设置 - 有道云笔记(本地文件) - 打开文件夹 使用typora打开有道云笔记目录: typora 菜单栏 - O ...
-
浅析b-树 b+树 以及Mysql的Innodb,Myisam引擎
B-树性质 B-树可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点. 1根节点至少有两个子节点 2每个节点有M-1个key,并且以升序排列 3位于M-1和M key的子节点的值位于 ...
-
SSM-网站后台管理系统制作(4)---Ajax前后端交互
前提:Ajax本身就为前后端交互服务的,实现功能:用户输入信息,实时判断用户的情况,这也是现在登录界面普遍流行的做法.前端js通过注释识别Controller层,该层查询返回,和之前Google验证码 ...
-
大数据学习笔记02-HDFS-常用命令
创建目录 hadoop fs -mkdir [-p] hdfs://master:9999/user/hadoop-twq/cmd 上传文件 hadoop fs -put [-f -d] [local ...
-
WinAPI: sndPlaySound - 播放 wav 文件
WinAPI: sndPlaySound - 播放 wav 文件 //声明: sndPlaySound( lpszSoundName: PChar; {声音文件} uFlags: UINT{播 ...
-
Redis基本数据类型介绍笔记
Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...
-
JavaScript document和window属性及方法详解
[document对象] 该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档. 属性 alinkColor 活动链接的颜色(ALINK) anchor 一个HTMI锚点 ...