文章目录
前言
之前的博客中都简单说了数据的渲染和导出excel文件。包括固定的 表头结构
,以及动态 表头和表数据
等方式。
本篇博客主要说明自定义命令
的方式,控制输出excel文件每行记录的行高
。
依赖引入
主要依赖以及版本如下所示:
xml
<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文件。代码如下所示:
java
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 类
实现。自定义命令需要定义命令名称
和命令逻辑
。如下所示:
java
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做填充渲染之前,补充命令和逻辑的调用。
java
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可以在模板中定义对应的单元格样式。只需要在模板中对需要做自动换行的列增加如下配置。
再次执行上述的代码逻辑,查看显示效果。