注:本文代码建立于前面写的代码。不过不看也不要紧。

前面的文章把JXLS 2.4.0 的基本使用写了一遍,现在讲讲一些更进一步的使用方法。我只写一些我用到过的方法,更多的高级使用方法请参考官网。

一、Map的应用

从一开始,官方dome使用的model中的引用对象一直都是一个javaBean对象。后来我发现其实可以直接往model中放一个map,然后也是直接用“点”的方式在excel中取出数据。

下面用第四篇文章——多sheet的源码做演示,我们先修改main方法,加入一个HashMapMap:

public static void main(String[] args) throwsException {//模板位置,输出流

String templatePath = "E:/template5_2.xls";

OutputStream os= new FileOutputStream("E:/out5_2.xls");

List list = generateData(); //模拟数据库获取数据//List page = DataByPage.byPage(list);//把获取的数据进行分页转换

List page = individual(list); //一页一个人//定义一个Map

Map tableInfo = new HashMap();

tableInfo.put("className", "六年三班2");

tableInfo.put("teacherComment", "已核实2");

tableInfo.put("directorComment", "已核实2");

Map model = new HashMap();

model.put("pages", page);

model.put("sheetNames", getSheetName(page));

model.put("tableInfo", tableInfo);//model.put("className", "六年三班");//model.put("teacherComment", "已核实");//model.put("directorComment", "已核实");

JxlsUtils.exportExcel(templatePath, os, model);

os.close();//删除多出来的sheet

DelSheet.deleteSheet("E:/out5_2.xls", "template");

System.out.println("完成");

}

把原来的model中put的多注释掉,然后把定义的Map tableInfo放入model中。

我们看看模板中怎么取:

直接取新加入的map的键名,再“点上”tableInfo的键名。

就这样轻松的取出来了。Map也是可以直接放进model中的,有时候Map用起来更加灵活,这就要自行选择了。

二、使用工具

工具的使用先看JxlsUtils类。

public classJxlsUtils{public static void exportExcel(InputStream is, OutputStream os, Map model) throwsIOException{

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 funcs = new HashMap();

funcs.put("utils", new JxlsUtils()); //添加自定义功能

evaluator.getJexlEngine().setFunctions(funcs);//必须要这个,否者表格函数统计会错乱

jxlsHelper.setUseFastFormulaProcessor(false).processTemplate(context, transformer);

}public static void exportExcel(File xls, File out, Map model) throwsFileNotFoundException, IOException {

exportExcel(new FileInputStream(xls), newFileOutputStream(out), model);

}public static void exportExcel(String templatePath, OutputStream os, Map model) throwsException {

File template=getTemplate(templatePath);if(template != null){

exportExcel(newFileInputStream(template), os, model);

}else{throw new Exception("Excel 模板未找到。");

}

}//获取jxls模版文件

public staticFile getTemplate(String path){

File template= newFile(path);if(template.exists()){returntemplate;

}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;

}

}

我们看到有一行:funcs.put("utils", new JxlsUtils());    //添加自定义功能

//函数强制,自定义功能

Map funcs = new HashMap();

funcs.put("utils", new JxlsUtils()); //添加自定义功能

evaluator.getJexlEngine().setFunctions(funcs);

这行代码的意思就是设置一个工具类JxlsUtils(),在excel中的引用为utils。当你在excel中使用utils时就会调用JxlsUtils()类(可以是其他的类)的对应方法。

我们来看下模板怎么写:

在模板中,你可以这样调用工具类:

${utils:ifelse(page.currentPage == page.tolalPage,"最后一页","")}

JXLS会自动找到utils这个键对应的值new JxlsUtils(),然后在JxlsUtils类中找对应的ifelse方法,然后根据方法接收的参数自动把你在excel写的参数传进去,再把方法的返回值显示在excel中。

还记得我前面保存进Page中的当前页码和总页码这两个属性吗?现在就是使用使用他们了。用他们可以判断现在的sheet是不是最后一页,最后一页可以显示一些别的数据。一般说ifelse这个已经够用了,但是如果你有更加复杂的操作,你也可以自行定制自己需要的工具类。

三、JXLS 是支持模板多个sheet输出数据的

这句话很奇怪,但是我一下子没想出别的表达。这个多sheet不是前面我们讲的分sheet,是说你模板有本身就已经有很多个sheet了,每个sheet显示的表都不一样,不用担心,你存放进model中的数据是可以跨sheet的。只要你想取出就能取出,这个我就不演示了。

四、页面边距bug

这个bug一般人是真没有发现的,但是对我来说就是差点要了老命....我们公司项目导出的excel报表比较大,一张A3纸都只是勉勉强强够打印。所以平常边距要设定得很小,这个边距的bug就是你在模板中设定的页面边距并不会拷贝进你导出的文件的。

你可能试验了一下说,没有啊,我的没问题啊。我说的不会拷贝仅是在分页分sheet导出时候出现的问题。我举个例子,你在模板中设定了页面边距,然后导出,JXLS会先把你的模板复制进导出的文件中,然后建立一个新的sheet,然后在根据模板的设定把内容拷贝进新sheet中,然后再建立新sheet不断循环。

问题就出现在把模板拷进新sheet的过程中,如果你改变了模板的页面边距,再进行一个分sheet导出,不要用POi删除导出文件第一页空的模板sheet,你查看第一页的页边距你发现是已经修改过的页边距,而你查看后面其他sheet的页边距就会是excel默认的页边距了。

不明白不要紧,你只要知道我已经解决了就好(新版本2.4.2我不知道作者有没有修复)。

问题就出现在这个PoiUtil的文件上,我们打开看看,看到copySheetProperties(Sheet src, Sheet dest)这个方法,这个方法就是拷贝sheet属性的。

public static voidcopySheetProperties(Sheet src, Sheet dest){

dest.setAutobreaks(src.getAutobreaks());

dest.setDisplayGridlines(src.isDisplayGridlines());

dest.setVerticallyCenter(src.getVerticallyCenter());

dest.setFitToPage(src.getFitToPage());

dest.setForceFormulaRecalculation(src.getForceFormulaRecalculation());

dest.setRowSumsRight(src.getRowSumsRight());

dest.setRowSumsBelow( src.getRowSumsBelow() );//增加页边距保存dest.setMargin(Sheet.TopMargin, src.getMargin(Sheet.TopMargin));

dest.setMargin(Sheet.LeftMargin, src.getMargin(Sheet.LeftMargin));

dest.setMargin(Sheet.RightMargin, src.getMargin(Sheet.RightMargin));

dest.setMargin(Sheet.BottomMargin, src.getMargin(Sheet.BottomMargin));

copyPrintSetup(src, dest);

}

这个方法内少写了对sheet页边距的拷贝,加上就行。加上后怎么放回包里?你可以自行打包....你也可以在你的项目目录上建立一个与PoiUtil类一模一样的路径,然后在里面放上修改后的类。Java在找包时候会优先找你写的路径,这样就覆盖掉了包路径了。

在src的根目录上,和com同级。

好了,这一篇文章就写到这里,写这篇文章时候我是懒的,我懒得再去做案例验证了,特别是最后的那个页边距的bug,我在当初我在网络上根本找不到和我一样的问题。我也是花了些功夫才找到这个原因的。本来我应该做下案例把这个bug讲清楚些,但是我写到这里我已经有些懒了.....说白了这个bug就是只有在分sheet导出时候才会出现的问题,能自己复现的就自己研究下,不能的,知道怎么解决了就行了。

下载PoiUtil类: 点这里下载

jxls模板hashmap_JXLS 2.4.0系列教程(五)——更进一步的应用和页面边距bug修复相关推荐

  1. ASP .NET Core Web Razor Pages系列教程五:更新Razor Pages页面

    系列文章目录:系列教程:使用ASP.NET Core创建Razor Pages Web应用程序 - zhangpeterx的博客 系列教程代码的GitHub地址:ASP .Net Core Razor ...

  2. 黄聪mysql_黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Acc

    企业库数据库访问模块通过抽象工厂模式 , 允许用户通过简单的配置选择不同的数据库作为程序的数据源 , 大大解决了切换数据库时带来的麻烦 . 因为我本机只安装了 SQL Server 2005, 所以在 ...

  3. 黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (高级)

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (高级) 本章介绍的是企业库加密应用程序模块 ...

  4. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之二应用知识梳理逻辑!

    原创PDF |<Android 深入系统完全讲解>免费开源,可能价值百万! 王姨劝我学HarmonyOS鸿蒙2.0系列教程之一环境搭建&&跑起来模拟器! 写完了第一篇,跑去 ...

  5. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之三Ability概述调用方法!

    原创PDF |<Android 深入系统完全讲解>免费开源,可能价值百万! 王姨劝我学HarmonyOS鸿蒙2.0系列教程之一环境搭建&&跑起来模拟器! 王姨劝我学Harm ...

  6. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之四Git搭建下载实例!

    原创PDF |<Android 深入系统完全讲解>免费开源,可能价值百万! 王姨劝我学HarmonyOS鸿蒙2.0系列教程之三Ability概述&&调用方法! 相信大家看了 ...

  7. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之六自定义View涂鸦项目实战!

    这一节写个简单的项目,涂鸦,简单来讲就是画什么,显示什么.最好的网站,就是官网,这里再发一下: https://developer.harmonyos.com/cn/docs/documentatio ...

  8. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之五布局方法点击响应!

    原创PDF |<Android 深入系统完全讲解>免费开源,可能价值百万! 王姨劝我学HarmonyOS鸿蒙2.0系列教程之三Ability概述&&调用方法! 为了更好的交 ...

  9. python3.6 django教程_【Python3.6+Django2.0+Xadmin2.0系列教程一】环境搭建及项目创建

    由于工作需要,接触了大半年时间的Django+xadmin框架,一直没空对这块对进行相关的梳理.最近在同事的怂恿下,就在这分享下笔者的学习及工作经验吧. 好了,话不多说,下面开始进入正题: 环境需求: ...

最新文章

  1. vue开发环境和生产环境里面解决跨域的几种方法
  2. Linux C编程--fork 详解
  3. Git clone时出现Please make sure you have the correct access rights and the repository exists.问题已解决。...
  4. 抢票 | AI未来说学术论坛第八期 深度学习特别专场
  5. [Java基础]多态基础
  6. 用udp协议通讯时怎样得知目标机是否获得了数据包?_和相亲对象聊天,你属于UDP还是CDP?...
  7. 公网访问阿里云数据库MongoDB——填坑笔记
  8. 三维ICP-SVD配准
  9. java里的stream,Java中的Stream
  10. 计算机怎么改鼠标标志,win10系统电脑的鼠标图标怎么修改
  11. 小觅深度相机标准版 ROS使用
  12. 最难忘的一节计算机课,难忘的一堂课作文(共10篇)
  13. 蓝桥杯 STEMA 考试选择题模拟题
  14. [扫盲教程]——Mac 新手最容易犯的几项错误
  15. Mysql数据库主主从设置
  16. 全球营商环境报告及数据(2004-2020年)
  17. VUE调用WEB3.0实现代币查询,批量转账功能
  18. Linux基础——makefile编写
  19. 超全,我梳理了最频繁使用的 70 个数据分析网址
  20. 浅析肖特基二极管与开关二极管的不同之处

热门文章

  1. 如何搭建大学生搜题公众号?
  2. MYSQL50道基础练习题
  3. Windows电脑挂载阿里云盘为本地磁盘(网络磁盘)
  4. 腾讯微博开放平台 android登录界面显示为pc登录界面 解决方案
  5. 计算机组成原理课程设计源码
  6. MySQL调优篇 | SQL调优实战(5)完结篇
  7. 7星彩随机N注选号程序
  8. 老庞互联网随想之一:世界从未改变!
  9. 【深度学习】自回归VS自编码
  10. Arduino使用磁簧开关