前言
之前的博客中都简单说了数据的渲染和导出excel文件。包括固定的表头结构,以及动态表头和表数据等方式。
本篇博客主要说明自定义命令的方式,控制输出excel文件每行记录的行高。
依赖引入
主要依赖以及版本如下所示:
<dependency> <groupid>org.jxls</groupid> <artifactid>jxls</artifactid> <version>2.4.5</version> </dependency> <dependency> <!-- 可以使用poi的实现也可以用jexcelapi的 --> <groupid>org.jxls</groupid> <artifactid>jxls-poi</artifactid> <version>1.0.15</version> </dependency> <dependency> <groupid>org.jxls</groupid> <artifactid>jxls-jexcel</artifactid> <version>1.0.7</version> </dependency> <dependency> <groupid>net.sf.jxls</groupid> <artifactid>jxls-core</artifactid> <version>1.0.6</version> </dependency>
绘制 jxls 批注的 excel 模板
其中两个批注分别如下:
- 整体数据范围:
administrator: jx:area(lastcell=”h3”)
- 列表数据渲染范围:
administrator: jx:each(items=“bdatas” var=“vo” lastcell=“h3” varindex=“ojbindex” )
测试类编写
编写一个简单的数据填充逻辑,并生成对应的excel文件。
代码如下所示:
import cn.xj.test.userpo; import com.google.common.collect.lists; import org.jxls.builder.xls.xlscommentareabuilder; import org.jxls.common.context; import org.jxls.util.jxlshelper; import org.springframework.core.io.classpathresource; import org.springframework.core.io.resource; import java.io.*; import java.util.*; public class test1 { public static void main(string[] args) throws ioexception { context context = new context(); // 数据集合 list<userpo> datalist = lists.newarraylist(); for (int i = 0; i < 10; i++) { userpo userpo = new userpo(); userpo.setnum("1_"+i); userpo.setname("xj_"+i); userpo.setage(i+1); userpo.setmail("专注写bug测试中文11111"); datalist.add(userpo); } // ${item.num} context.putvar("bdatas",datalist); // 模板文件再resources 目录下 resource resource = new classpathresource("/report/test_user1.xlsx"); inputstream is = resource.getinputstream(); string outfile = system.getproperty("user.dir")+ file.separator+"springboot-poi"+file.separator+"pdf"+file.separator+system.currenttimemillis()+ ".xlsx"; outputstream outputstream = new fileoutputstream(outfile); jxlshelper jxlshelper = jxlshelper.getinstance(); jxlshelper.getareabuilder().gettransformer(); jxlshelper.processtemplate(is, outputstream, context); // jxlshelper.getinstance().processtemplate(is, outputstream, context); } }
执行后,生成excel文件中内容的效果如下所示:
每行的行高太大,毕竟再模板中就是配置的这么大,显得很散乱。
此时则可以使用自定义命令的方式,动态地修改行高。
自定义命令
jxls中自定义命令,可以采取继承 abstractcommand 类实现。自定义命令需要定义命令名称和命令逻辑。
如下所示:
import org.apache.poi.ss.usermodel.row; import org.apache.poi.ss.usermodel.sheet; import org.jxls.area.area; import org.jxls.command.abstractcommand; import org.jxls.common.cellref; import org.jxls.common.context; import org.jxls.common.size; import org.jxls.transform.poi.poitransformer; /** * 自定义列高指令 * 如: * jx:autorowheight(lastcell ="c3") * * 还需要在对应的主程序中调用 */ public class autorowheightcommand extends abstractcommand { /** * 批注中的自定义指令 * @return */ @override public string getname() { return "autorowheight"; } /** * 列高逻辑 * @param cellref * @param context * @return */ @override public size applyat(cellref cellref, context context) { area area=getarealist().get(0); size size = area.applyat(cellref, context); poitransformer transformer = (poitransformer) area.gettransformer(); sheet sheet = transformer.getworkbook().getsheet(cellref.getsheetname()); // list bdatas = (list) context.getvar("bdatas"); // int firstdefaultcol = cellref.getcol(); // 最开始的第一列 // if(!collectionutils.isempty(bdatas)){ // for (int i = 0; i < bdatas.size(); i++) { // // 计算中文、字符的长度 设定列宽 // object data = bdatas.get(i); // if(!stringutils.isempty(data) && (data.getbytes().length+4)>sheet.getcolumnwidth(i)){ // sheet.setcolumnwidth(i+firstdefaultcol,data.getbytes().length+4); // }else{ // sheet.setcolumnwidth(i+firstdefaultcol,30); // 默认 // } // // } // } //sheet.setcolumnwidth(cellref.getcol(),50); row row = sheet.getrow(cellref.getrow()); row.setheight((short) -1); return size; } }
自定义命令后,需要再模板中增加命令的标识,否则不会生效。
jx:autorowheight(lastcell =“h3”)
其次,还需要再调用jxls做填充渲染之前,补充命令和逻辑的调用。
import cn.xj.jxls.autorowheightcommand; import cn.xj.test.userpo; import com.google.common.collect.lists; import org.jxls.builder.xls.xlscommentareabuilder; import org.jxls.common.context; import org.jxls.util.jxlshelper; import org.springframework.core.io.classpathresource; import org.springframework.core.io.resource; import java.io.*; import java.util.*; public class test1 { public static void main(string[] args) throws ioexception { context context = new context(); // 数据集合 list<userpo> datalist = lists.newarraylist(); for (int i = 0; i < 10; i++) { userpo userpo = new userpo(); userpo.setnum("1_"+i); userpo.setname("xj_"+i); userpo.setage(i+1); userpo.setmail("专注写bug测试中文11111"); datalist.add(userpo); } // ${item.num} context.putvar("bdatas",datalist); // 模板文件再resources 目录下 resource resource = new classpathresource("/report/test_user1.xlsx"); inputstream is = resource.getinputstream(); string outfile = system.getproperty("user.dir")+ file.separator+"springboot-poi"+file.separator+"pdf"+file.separator+system.currenttimemillis()+ ".xlsx"; outputstream outputstream = new fileoutputstream(outfile); jxlshelper jxlshelper = jxlshelper.getinstance(); jxlshelper.getareabuilder().gettransformer(); // 渲染前 载入 自定义 命令 xlscommentareabuilder.addcommandmapping("autorowheight", autorowheightcommand.class); jxlshelper.processtemplate(is, outputstream, context); } }
执行后的效果如下所示:
关于自动换行
jxls没有对应的自动换行操作,但是jxls可以在模板中定义对应的单元格样式。只需要在模板中对需要做自动换行的列增加如下配置。
再次执行上述的代码逻辑,查看显示效果。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论