jxls2.3-简明教程
jxls是一个简单的、轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局。java中成熟的excel导出工具有pol、jxl,但他们都是使用java代码的方式来导出excel,编码效率很低且不方便维护。
另外,jxls2.3的运行效率也相当不错,经过测试,在禁用日志输出的情况下,导出excel单表66535条记录仅仅3000毫秒,与poi几乎没什么大的差距。
demo工程源码下载:https://files.cnblogs.com/files/klguang/jxls-demo.zip
springboot-demo下载:https://files.cnblogs.com/files/klguang/jxls-springboot.zip
excel模板示例:

Excel模板标记在jxls中的作用分为三部分:
- bean属性标记
- XLS Area定义标记
- XLS Command表示标记
bean属性标记
jxls使用 Apache JEXL表达式语言来解析定义在excel模板中的表达式。JEXL与JSTL相似,并对JSTL进行了扩展。eg:
${department.chief.age} //属性可以是无限深度
${utils:dateFmt(date,"yyyy-MM-dd")} //自定义工具函数
XLS Area定义标记
XLS Area 是JxlsPlus中的一个重要概念,它代表excel模板中需要被解析的矩形区域,由A1到最后一个单元格表示,有利于加快解析速度。
XLS Area 使用excel注释标注表示,它需要被定义在excel 模板的第一个单元格(A1):
jx:area(lastCell = "<AREA_LAST_CELL>")
这个标记定义了excel模板需要被解析的矩形区域为:A1到<AREA_LAST_CELL>。
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")
each 可以有如下一些属性:
- items 上下文中集合的变量名;
- var 在遍历集合的时候每一条记录的变量名;
- area 该XLS Command的解析区域;
- direction 数据在excel中填充的方向,默认(DOWN)向下;
- select 其值为一个表达式,用来过滤数据。
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);
demo
此demo是将简单的员工信息导出excel,demo工程源码下载:http://files.cnblogs.com/files/klguang/jxlsdemo.zip
工程目录:

Employee.java
public class Employee {
private String name;
private Date birthDate;
private BigDecimal payment;
private BigDecimal bonus;
// getter and setter
}
建立excel模板:

工具类JxlsUtils.java
public class JxlsUtils {
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 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 ObjectCollectionDemoXlsx {
static Logger logger = LoggerFactory.getLogger(ObjectCollectionDemoXlsx.class);
public static void main(String[] args) throws ParseException, IOException {
logger.info("Running Object Collection demo");
List employees = generateSampleEmployeeData();
OutputStream os = new FileOutputStream("target/object_collection_output.xlsx");
Map model=new HashMap();
model.put("employees", employees);
model.put("nowdate", new Date());
InputStream inputStream = ObjectCollectionDemoXlsx.class.getClassLoader()
.getResourceAsStream("jxls-template/object_collection_template.xlsx");
JxlsUtils.exportExcel(inputStream, os, model);
os.close();
}
public static List generateSampleEmployeeData() throws ParseException {
List employees = new ArrayList();
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;
}
}
生成效果:

jxls2.3-简明教程的更多相关文章
- 2013 duilib入门简明教程 -- 第一个程序 Hello World(3)
小伙伴们有点迫不及待了么,来看一看Hello World吧: 新建一个空的win32项目,新建一个main.cpp文件,将以下代码复制进去: #include <windows.h> #i ...
- 2013 duilib入门简明教程 -- 部分bug (11)
一.WindowImplBase的bug 在第8个教程[2013 duilib入门简明教程 -- 完整的自绘标题栏(8)]中,可以发现窗口最大化之后有两个问题, 1.最大化按钮的样式 ...
- 2013 duilib入门简明教程 -- 部分bug 2 (14)
上一个教程中提到了ActiveX的Bug,即如果主窗口直接用变量生成,则关闭窗口时会产生崩溃 如果用new的方式生成,则不会崩溃,所以给出一个临时的快速解决方案,即主窗口 ...
- 2013 duilib入门简明教程 -- 自绘控件 (15)
在[2013 duilib入门简明教程 -- 复杂控件介绍 (13)]中虽然介绍了界面设计器上的所有控件,但是还有一些控件并没有被放到界面设计器上,还有一些常用控件duilib并没有提供(比如 ...
- 2013 duilib入门简明教程 -- 事件处理和消息响应 (17)
界面的显示方面就都讲完啦,下面来介绍下控件的响应. 前面的教程只讲了按钮和Tab的响应,即在Notify函数里处理.其实duilib还提供了另外一种响应的方法,即消息映射DUI_BEG ...
- 2013 duilib入门简明教程 -- FAQ (19)
虽然前面的教程几乎把所有的知识点都罗列了,但是有很多问题经常在群里出现,所以这里再次整理一下. 需要注意的是,在下面的问题中,除了加上XML属性外,主窗口必须继承自WindowImpl ...
- Mac安装Windows 10的简明教程
每次在Mac上安装Windows都是一件非常痛苦的事情,曾经为了装Win8把整台Mac的硬盘数据都弄丢了,最后通过龟速系统恢复模式恢复了MacOSX(50M电信光纤下载了3天才把系统下载完),相信和我 ...
- Docker简明教程
Docker简明教程 [编者的话]使用Docker来写代码更高效并能有效提升自己的技能.Docker能打包你的开发环境,消除包的依赖冲突,并通过集装箱式的应用来减少开发时间和学习时间. Docker作 ...
- 2013 duilib入门简明教程 -- 总结 (20)
duilib的入门系列就到尾声了,再次提醒下,Alberl用的duilib版本是SVN上第个版本,时间是2013.08.15~ 这里给出Alberl最后汇总的一个工程,戳我下载,效 ...
- plain framework 1 参考手册 入门指引之 简明教程
简明教程 简单的例子 实现代码 简单的例子 如果你已经下载好整个框架的源码,那么你可以在这里找到应用的例子: plainframework/applications/pf_simple 如果你在win ...
随机推荐
- HTML5语义化标签重构页面
在HTML5未出现之前我们都用div+css来构建页面,比如<div id=”header”>,div的滥用,使得代码的可读性和可维护性很差,现在用本文来介绍一下用HTML5′干净的’语义 ...
- ARM的启动代码(1):介绍(转)
源:ARM的启动代码(1):介绍 很多朋友搞嵌入式,写起代码来一点问题没有,到最后上板子调试的时候,挂了.究其原因,还是对芯片的启动地址.启动方式.bootloader和操作系统的衔接出了问题.今天就 ...
- 【转】每一个程序员需要了解的10个Linux命令
作为一个程序员,在软件开发职业生涯中或多或少会用到Linux系统,并且可能会使用Linux命令来检索需要的信息.本文将为各位开发者分享10个有用的Linux命令,希望对你会有所帮助. 以下就是今天我们 ...
- JQueryUI确认框 confirm
$(function(){ $('#AlertMsg').dialog({ autoOpen: false, width: 300, modal: true, position: 'center', ...
- win7 下安装 ubuntu 16.04双系统
Ubuntu 每年发布两个版本,目前最新正式版版本也升到了 16.04.Ubuntu 16.04 开发代号为"Xenial Xerus",为第六个长期支持(LTS)版本,其主要特色 ...
- javascript-函数及兼容
1.事件绑定,删除,传播,默认方式,获取类型的兼容 var eventList = { //添加事件兼容 addEvent:function (event,type,backevent) { if ( ...
- STM8S003/005/007芯片解密单片机解密程序提取复制经验分享!
STM8S003/005/007芯片解密单片机解密程序提取复制 芯片解密型号: STM8S003K3T6,STM8S005K6T6,STM8S007C8T6,STM8S003F3P6 STM8S005 ...
- JavaScript原生的节点操作
前言:原生是Javascript的基础,还是需要多多重视,时间长都忘记了,现在整理一下. 获取子节点 children 不是标准的dom属性,但是几乎被所有浏览器支持.不包含文本节点. 注意:在IE中 ...
- ajax数据交互(arcgis server)
通过ajax来调用服务器map数据,来实现搜索功能. 效果: 1.我要搜索下中国移动的地理信息: 2.会搜出17条消息,然后把他们分页显示,一页6条: 3.每一页的6天数据,会在map生成一个6条ma ...
- 微信小程序开发系列(二)小程序的全局文件
其实你已经知道了小程序的文件结构 上一节讲到,小程序的页面由三部分组成: 视图(.wxml).逻辑(.js).样式(.wxss). 我们这次重新展开文件结构: 小程序用到的文件类型只有四种,正如你所看 ...