LXLS 2.4.0 简介

jxls2.4 是java对excel操作的工具包,可以很方便的实用模板输出excel,根据xml配置读取excel内容。

对比jxls1 现在的版本使用批注的模式运行指令,可以支持excel中使用公式,07的excel。官网

使用:

maven中添加依赖

org.jxls

jxls

2.4.5

org.jxls

jxls-poi

1.0.15

org.jxls

jxls-jexcel

1.0.7

导出EXCEL

基础介绍

使用批注的模式编写指令

需在excel的第一个单元格指定整个模板的范围

单元格中取值与el表达式类似使用${}来访问传入的变量

指令中需要访问对象则不需要使用${} 直接访问即可,需用""包裹

常用指令说明:

jx:each 循环

示例:jx:each((items="employees" var="employee" lastCell="D4" area="[A4:D4]" select="employee.payment > 2000"))

参数说明:

参数名称

示例

必填

说明

items

items="employees"

必填

循环的集合对象

var

var="employee"

必填

循环中的变量名,指定之后区域内可以使用该名称访问属性

lastCell

lastCell="D4"

必填

指令对应的结束位置

direction

direction ="RIGHT"

输出的方向向下(DOWN)或向右(RIGHT),默认为DOWN

area

areas=["A8:F8","A13:F13"]

循环的区域,一次循环多行则需要填写,可以指定多个区域使用逗号分隔

select

select="employee.payment>2000"

过滤条件,不需要通过${}来取值

groupBy

groupBy ="name"

jx:each(items="employees" var="nameGroup" groupBy="name" groupOrder="asc" lastCell="D7")依据employee中name进行分组,分组后的集合可通过nameGroup.items来获取,官网示例中后面还有一个each指定的items就是nameGroup.items

groupOrder

groupOrder ="asc"

指定分组排序(‘desc’ or ‘asc’)

multisheet

multisheet ="sheets"

循环的sheet名称集合,指定后会产生多个sheet,指定后each的维度会变为sheet,不需要指定area

shiftMode

shiftMode ="adjacent"

adjacent指定后通过添加行的方式向指定方向输出,inner:则为通过添加单元格的方式向指定方向输出,默认为inner

cellRefGenerator

?

?

不指定shiftMode ="adjacent"的效果

jx:if 条件判断

示例:jx:if(condition="department.chief.name != 'Betsy' " lastCell="F4" areas=["A3:F4"])

参数名称

示例

必填

说明

condition

condition="department.chief.name != 'Betsy' "

必填

判断条件,字符串不需要通过${}来取值,直接访问传递对象的内容

ifArea

ifArea =["A3:F4"]

if指令影响的范围 condition结果为true则显示指定范围

elseArea

elseArea=["A3:F4"]

if指令影响的范围 condition结果为false则显示指定范围

jx:updateCell 动态输出公式

说明:主要用于动态修改模板中被循环包裹的的公式,demo中的相关例子在org.jxls.demo.SxssfDemo中

示例:jx:updateCell(lastCell="E4" updater="totalCellUpdater")

参数名称

示例

必填

说明

updater

updater="totalCellUpdater"

必填

指定具体的操作类需实现CellDataUpdater接口

java代码示例:

static class TotalCellUpdater implements CellDataUpdater{

/**

* cellData 批注对应的单元格

* targetCell 输出的单元格

* context 模板中的上下文通过getVar(变量名)来获取传入的对象

*/

@Override

public void updateCellData(CellData cellData, CellRef targetCell, Context context) {

if( cellData.isFormulaCell() && cellData.getFormula().equals("SUM(E2)")){

String resultFormula = String.format("SUM(E2:E%d)", targetCell.getRow());

cellData.setEvaluationResult(resultFormula);

}

}

}

jx:grid 输出一个表格

说明:一次性输出一个表格包含表头表体,demo中的相关例子在org.jxls.demo.GridCommandDemo中

示例:jx:grid(lastCell="A4" headers="headers" data="data" areas=[A3:A3, A4:A4] formatCells="BigDecimal:C1,Date:D1")

参数名称

示例

必填

说明

headers

headers="headers"

必填

循环的表头内容为List ,表头和表体没有必然的关系,可以多一列也可以少一列

data

data="data"

必填

循环的表体内容为List/List,当为javabean时java代码中需指定读取的属性名称

formatCells

formatCells="BigDecimal:C1,Date:D1"

指定单元格格式化方式

java代码示例:

try(InputStream is = GridCommandDemo.class.getResourceAsStream("grid_template.xls")) {

try(OutputStream os = new FileOutputStream("grid_output2.xls")) {

Context context = new Context();

context.putVar("headers", Arrays.asList("Name", "Birthday", "Payment"));

context.putVar("data", employees);

//当循环的表体为javabean时指定读取的属性,Sheet2!A1表示输出开始的位置

JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "name,birthDate,payment,bonus", "Sheet2!A1");

}

}

jx:image 输出图片

说明:输出一张图片,demo中的相关例子在org.jxls.demo.ImageDemo中

示例:jx:image(lastCell="D10" src="data:image" imageType="PNG")

参数名称

示例

必填

说明

src

src="data:image"

必填

输出的图片数据源byte[]

imageType

imageType="PNG"

输出的图片格式可不填

java代码示例:

public static void execute2() throws IOException {

try(InputStream is = ImageDemo.class.getResourceAsStream(template2)) {

try (OutputStream os = new FileOutputStream(output2)) {

Context context = new Context();

InputStream imageInputStream = ImageDemo.class.getResourceAsStream("business.png");

byte[] imageBytes = Util.toByteArray(imageInputStream);

Department department = new Department("Test Department");

department.setImage(imageBytes);

context.putVar("dep", department);

JxlsHelper.getInstance().processTemplate(is, os, context);

}

}

}

EXCEL中使用公式

使用 来 使 用 中 的 公 式 例 如 [ ] 来 使 用 e x c e l 中 的 公 式 例 如 " [B4(1+${bonus})]"输出后为"=B6(1+0.1)",可以使用excel函数如SUM如选择某一列只需指定变量对应单元格,输出会自动替换为该列,如下图

如公式中不需要访问传入属性直接写=SUM(B4)编译后也会自动替换为=SUM(B4:B8)

支持java手动增加公式详细例子请看demo中org.jxls.demo.FormulaExportDemo

自定义

函数和指令都可以进行扩展,需在导出前进行初始化,原文顺便吐槽一下百度用标题查居然第一个出来的是转发的第三个才是原文。

具体的内容可以参考大神写的这个项目jxlss

函数

函数:在单元格中使用处理具体数据

JxlsHelper jxlsHelper = JxlsHelper.getInstance();

Transformer transformer = jxlsHelper.createTransformer(is, os);

JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) transformer.getTransformationConfig().getExpressionEvaluator();

Map functions = new HashMap<>(1);

//添加自定义功能

functions.put("util", new JxlsUtil());//此处util为函数前缀,调用时在单元格中使用${util:函数名(参数)}来使用其中参数为当前上下文内容

evaluator.getJexlEngine().setFunctions(functions);

jxlsHelper.processTemplate(context, transformer);

is.close();

//JxlsUtil 格式化工具类

public class JxlsUtil {

/**

* 日期格式化

*

* @param date

* @param fmt

* @return

*/

public String dateFmt(Date date, String fmt) {

if (date == null) {

return null;

}

try {

SimpleDateFormat dateFmt = new SimpleDateFormat(fmt);

return dateFmt.format(date);

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

/**

* 返回第一个不为空的对象

*

* @param objs

* @return

*/

public Object defaultIfNull(Object... objs) {

for (Object o : objs) {

if (o != null) {

return o;

}

}

return null;

}

/**

* if判断

*

* @param b

* @param o1

* @param o2

* @return

*/

public Object ifelse(boolean b, Object o1, Object o2) {

return b ? o1 : o2;

}

}

指令

指令:在批注中使用,可扩展原有jxls中的功能例如循环增加下标.

继承AbstractCommand

//扩展指令

public class ExEachCommand extends AbstractCommand {

//处理内容

public Size applyAt(CellRef cellRef, Context context) {}

....

}

//在具体导出的类中增加静态代码块,由于只需要执行一次所以用静态代码块比较合适

static {

//添加自定义指令(可覆盖jxls原指令)

XlsCommentAreaBuilder.addCommandMapping("each",ExEachCommand.class);

}

读取Excel

通过一个xml来对应excel中内容,读取时传入相应xml和excel来转换为javabean,

转换代码:

try (InputStream xmlInputStream = EquipmentController.class.getResourceAsStream("/excelTemp/equipment_impot.xml")) {

File tempfile = fileService.getFile(data, fileType, file);

XLSReader reader = ReaderBuilder.buildFromXML(xmlInputStream);

try (InputStream xlsInputStream = new FileInputStream(tempfile)) {

List equipments = new ArrayList<>();

Map beans = new HashMap<>(15);

Map title = new HashMap<>(3);

beans.put("equipments", equipments);

beans.put("title", title);

//碰到数据类型转换异常时跳过异常,例如数字类型但是单元格中为空,默认是会抛出异常的.设置之后就会设置为null

ReaderConfig.getInstance().setSkipErrors(true);

//从excel中读取对象,名称需和xml中对应

reader.read(xlsInputStream, beans);

if (checkTitle(title)) {

message = equipmentService.importEquipment(equipments, firmInfo);

} else {

throw new BusinessAjaxException(TEMPLET_ERROR);

}

if (StringUtils.isBlank(message)) {

message = SUCCESS_CONTENT;

} else {

data.put("status", HttpStatus.UNPROCESSABLE_ENTITY.value());

}

data.put("message", message);

}

} catch (BusinessAjaxException e) {

throw e;

} catch (XLSDataReadException e) {

throw new BusinessAjaxException(String.format(JXLS_ERROR, e.getCellName()), e);

} catch (Exception e) {

throw new BusinessAjaxException(IMPORT_ERROR, e);

}

对应xml文件:

title.eqCode

title.origin

title.remark

equipment.eqCode

equipment.eqName

equipment.brand

equipment.importBuyTime

equipment.importSpecification

equipment.price

equipment.origin

equipment.quantity

equipment.process

equipment.numberUsers

equipment.equipmentTrip

equipment.eqPrecision

equipment.remark

注意事项:

读取的数据类型为日期时数据转换很麻烦,所以我在这里是增加了一个字符串属性用于存储读取的内容,然后在java中进行格式转换,如有更好的解决方案望告知

如属性中包含非字符串属性,excel中又可以不填需增加设置:ReaderConfig.getInstance().setSkipErrors(true)避免中止导入

最好手动捕获XLSDataReadException 异常,e.getCellName()可以拿到具体导入报错的单元格,能精确定位

参考资料:

jxls对比_JXLS 2.4.0学习相关推荐

  1. Zabbx6.0(学习笔记)

    Zabbx6.0(学习笔记) 目录导航 Zabbx6.0(学习笔记) 一.为什么 需要监控系统 二.如何选择监控 三.Zabbix概述 四.Zabbix安装哪个版本? Zabbix安装要求 1.硬件 ...

  2. vue 3.0学习1

    vue 3.0学习 一.vue 3.0 diff算法优化 1.vue 3.0六大亮点 2.vue 3.0 如何变快的? 1. diff方法优化 https://vue-next-template-ex ...

  3. flink1.12.0学习笔记第2篇-流批一体API

    flink1.12.0学习笔记第 2 篇-流批一体API flink1.12.0学习笔记第1篇-部署与入门 flink1.12.0学习笔记第2篇-流批一体API flink1.12.0学习笔记第3篇- ...

  4. flink1.12.0学习笔记第1篇-部署与入门

    flink1.12.0学习笔记第 1 篇-部署与入门 flink1.12.0学习笔记第1篇-部署与入门 flink1.12.0学习笔记第2篇-流批一体API flink1.12.0学习笔记第3篇-高级 ...

  5. [Paddle2.0学习之第四步](下)词向量之CBOW

    [Paddle2.0学习之第四步]词向量之CBOW 项目已放在aistudio: [Paddle2.0学习之第四步](下)词向量之CBOW 文章目录 [Paddle2.0学习之第四步]词向量之CBOW ...

  6. mysql5.0镜像_Mysql5.0学习笔记(一)

    Mysql5.0学习笔记(一) -基本sql语句与支持字符集 1.登录 mysql -h localhost -u root 2.创建用户firstdb(密码firstdb)和数据库,并赋予权限于fi ...

  7. asp.net2.0学习历程 菜鸟到中级程序员的飞跃【月儿原创】

    asp.net2.0学习历程 菜鸟到中级程序员的飞跃 --30本好书点评 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/           时间:2007.5.1 ...

  8. [EntLib]微软企业库5.0 学习之路——第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——上篇...

    本文是为后面的学习之路做铺垫,简单介绍下企业库中的Validation模块的一些相关知识,包括Validation模块的简介.用途.使用方法.默认提供的多种验证器的介绍等. 一.简介及用途 在实际的项 ...

  9. tensorflow 1.0 学习:参数和特征的提取

    tensorflow 1.0 学习:参数和特征的提取 在tf中,参与训练的参数可用 tf.trainable_variables()提取出来,如: #取出所有参与训练的参数 params=tf.tra ...

  10. ASP.NET MVC 3.0学习系列文章—Model in ASP.NET MVC 3.0

    系列文章 ASP.NET MVC 3.0学习系列文章-序 ASP.NET MVC 3.0学习系列文章--Razor and ASP.NET MVC 3.0 ASP.NET MVC 3.0学习系列文章- ...

最新文章

  1. 于正AI换脸火上热搜,差点骗了全网!古风民族风也能任意切换
  2. 影响堪比登月!谷歌等设计DL新方式让神经网络无限深无限窄
  3. Quzrtz.net 示例
  4. JSON In Code
  5. mysql 57授权失败_MYSQL教程完美解决mysql客户端授权后连接失败的问题
  6. 正确理解hibernate的inverse属性
  7. Linux命令之basename 命令
  8. 高并发与负载均衡-nginx-反向代理概念
  9. 20172315 2017-2018-2 《程序设计与数据结构》实验三报告
  10. freescale 基于arm m0的单片机
  11. 像素生存者2为什么显示服务器不可用,像素生存者2为什么更新了玩不了 | 手游网游页游攻略大全...
  12. AVR单片机简单介绍(基于atmega128)
  13. 【Paper】DeepConvLSTM:Deep Convolutional and LSTM RNN for Multimodal Wearable Activity Recognition
  14. FigDraw 11. SCI 文章绘图之小提琴图 (ViolinPlot)
  15. 基于flex/bison工具生成sysY2022文法的词法/语法分析器
  16. 漫谈Commons-Collections反序列化
  17. 树莓派播放音频时3.5mm接口没有声音怎么办?
  18. 1678. 设计 Goal 解析器
  19. window.open浏览器弹出新窗口被拦截—原因分析和解决方案
  20. 东莞市速网五金制品有限公司1*4光纤笼子规格书

热门文章

  1. linux线程互踩,IOS 多线程漫漫谈(Process and Thread)
  2. oracle财务系统表,Oracle ERP 财务模块表结构.ppt
  3. 【前端】【HTML+CSS+JavaScript(JS)】简易工资计算器的实现
  4. js 下载文件、音频、视频
  5. php之sprintf的用法,PHP之sprintf函数用法详解
  6. 软件安全测试是为了什么,一航软件测评有这些见解
  7. 怎样搬运视频不侵权,王者剪辑的指纹检测如何检测原创度
  8. 一款非常优秀的内存数据库——lmdb
  9. NOIP2016提高组 day1
  10. 上海大华条码称代码_上海大华条码秤使用说明书样本