最近业务提了一个导出excle报表的功能需求,而之前我记忆中的导出功能,都是直接使用代码画表格的方式,往往是一大坨代码,看着就让人头大。于是我就想着有没有基于excle模板直接替换变量的方式呢,于是就找到jxls,的确很简单,数行代码就解决了我的导出需求,甚是欢喜。特此根据网上查询的资料和自己的实践,整理一下笔记,以便后期学习回顾,也期望能帮助到其他人。
直接上代码,代码有注释,注释很详细,注意看注释
添加pom依赖或Jar依赖
net.sf.jxls
jxls-core
1.0.3
导出功能在和我原来旧的项目融合时,是只添加了jxls-core即可。但在我搭建的单独测试工程中,还另外依赖了如下的依赖包。
1. 使用jxls基于模板导出单个sheet的excle
1.1 单sheet模板样式
一般数据直接绑定跟 jstl比较像,直接${name},循环就是
,上图中红色框框住的区间就是列表遍历的位置。
1.2 单sheet代码演示
代码具体含义,详见注释:
import net.sf.jxls.transformer.XLSTransformer;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Test;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JxlsDemo {
@Test
public void method1() throws Exception {
// 循环数据
List
1.3 单sheet导出效果
2. 使用jxls基于模板导出带有多个sheet的excle
2.1 多sheet模板样式
代码具体含义,详见注释:
2.2 多sheet模板导出代码
@Test
public void method2() throws Exception {
// 循环数据
List
2.3 多sheet导出效果
3 使用jxls基于模板导出复杂sheet的excle
3.1 模板和导出结果样例
3.2 复杂sheet模板导出代码
@Test
public void genComplexExcle() throws Exception {
// 循环数据
List list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Company company = new Company();
company.setName("名称" + Math.random() * 100);
company.setAddress("地址" + Math.random() * 100);
company.setAge((int) (Math.random() * 100));
list.add(company);
}
List list2 = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Company company = new Company();
company.setName("名称2" + Math.random() * 100);
company.setAddress("地址2" + Math.random() * 100);
company.setAge((int) (Math.random() * 100));
list2.add(company);
}
// 表格使用的数据
Map map = new HashMap();
map.put("data", list);
map.put("data2", list2);
map.put("title", "这个是标题");
map.put("val", "这是演示合并单元格的填值情况");
map.put("adminName", "戴晓年");
map.put("adminClass", "2021-100班");
// 获取模板文件
InputStream is = this.getClass().getClassLoader().getResourceAsStream("temp03.xls");
// 实例化 XLSTransformer 对象
XLSTransformer xlsTransformer = new XLSTransformer();
// 获取 Workbook ,传入 模板 和 数据
Workbook workbook = xlsTransformer.transformXLS(is, map);
// 写出文件
OutputStream os = new BufferedOutputStream(new FileOutputStream("D://companys2021complex.xls"));
// 输出
workbook.write(os);
// 关闭和刷新管道,不然可能会出现表格数据不齐,打不开之类的问题
is.close();
os.flush();
os.close();
}
4. web环境下运行
web环境下跑和上面的代码基本上一样,不一样的就是 OutputStream 的地方换成了 response.getOutputStream(),然后 response 设置一下文件名,response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("报表.xls" ,"UTF-8"));
代码如下:
@RestController
@RequestMapping(value = "/report")
public class ReportController {
private final static Logger LOGGER = LoggerFactory.getLogger(ReportController.class);
@RequestMapping(value = "/downLoadDataFile/{createdMonth}", method = RequestMethod.GET)
public String downLoadDataFile(HttpServletResponse response,@PathVariable String createdMonth) throws Exception {
InputStream is = null;
OutputStream os = null;
LOGGER.info("downLoadDataFile createdMonth : -> [{}]", createdMonth);
try {
// 循环数据
List list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Student student = new Student();
student.setAge1((int) (Math.random() * 100)+"字符串");
student.setAge2((int) (Math.random() * 100));
student.setAge3((int) (Math.random() * 100));
student.setAge4((int) (Math.random() * 100));
student.setAge5((int) (Math.random() * 100));
student.setAge6((int) (Math.random() * 100));
list.add(student);
}
// 表格使用的数据
Map map = new HashMap();
map.put("data", list);
map.put("title", "java基于模板导出");
map.put("val", "演示合并单元格");
// 获取模板文件
is = this.getClass().getClassLoader().getResourceAsStream("temp02.xls");
// 实例化 XLSTransformer 对象
XLSTransformer xlsTransformer = new XLSTransformer();
// 获取Workbook,传入 模板 和 数据
Workbook workbook = xlsTransformer.transformXLS(is, map);
// 写出文件
// 设置文件名
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("报表224.xls" ,"UTF-8"));
// 写出文件
os = new BufferedOutputStream( response.getOutputStream() );
// 输出
workbook.write(os);
return "Downloading...";
} catch (Exception e) {
LOGGER.error("DOWNLOAD data FILE THROW EXCEPTION:" + e.getMessage(), e);
return "Error";
} finally {
if (os != null) {
os.flush();
os.close();
}
if (is != null) {
is.close();
}
}
}
}
5.参考文档
https://blog.csdn.net/yali_aini/article/details/85804466
https://www.cnblogs.com/haoxiu1004/p/7799028.html
https://www.jianshu.com/p/1f821b519374