Excel导出功能
在我们开发项目的时候,难免会遇到客户需要将表格数据导出到Excel中,进行打印或者留存,于是Java对Excel、word的操作都必不可少。
关于这些操作Excel目前有两个框架,一个是apache 的poi, 另一个是 Java Excel
Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,译为“可怜的模糊实现”。
官方主页: http://poi.apache.org/index.html
API文档: http://poi.apache.org/apidocs/index.html
Java Exce在此不做介绍,此次要讲的是在Hutool工具类库中对Excel表格的操作。
首先介绍下Hutool工具类,他是由我们中国开发人员封装的一个maven库
官方主页以及API文档:https://hutool.cn/docs
截取一点小简介:
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语 言也可以“甜甜的”。
Hutool中的工具方法来自于每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。
下面进入主题:用Hutool中ExcelUtil对Excel的导出。
首先要先导入两个依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!--hutool 类库依赖,我在这导入的全部,也可以根据官方文档导入所需要的-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>
之后我自己写了一个ExcelUtils工具类,对ExcelUtil中的导出操作进行整理,方便更多的类调用。
代码的调整:
1、关于excel样式调整,在文档中有详细介绍,我只是改变了一下字体大小以及字体样式。(原生的真的太小了)
2、解决了Excle文件名为汉字会乱码的问题。
3、关于几个参数,在代码中有注释。
public class ExcelUtils {
/**
* 导出excel
* @param response
* @param rows 查到的数据集合
* @param title Excel表头名称
* @param excelName Excel表名
* @return
*/
public static boolean writerDownLoad(HttpServletResponse response, HttpServletRequest request,List<List<String>> rows, String title, String excelName){
ExcelWriter writer = ExcelUtil.getWriter();
Font font = writer.createFont();
font.setFontHeight((short) 280);
font.setFontName("宋体");
writer.getStyleSet().setFont(font, false);
writer.merge(rows.get(0).size() - 1, title);
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
//response为HttpServletResponse对象
response.setContentType("application/vnd.ms-excel;charset=utf-8");
//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
//编码开始
String userAgent = request.getHeader("User-Agent");
try {
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
excelName = java.net.URLEncoder.encode(excelName, "UTF-8");
} else {
// 非IE浏览器的处理:
excelName = new String(excelName.getBytes("UTF-8"), "ISO-8859-1");
}
}catch (Exception e){
e.printStackTrace();
}
//编码结束
response.setHeader("Content-Disposition","attachment;filename="+excelName+".xls");
ServletOutputStream out= null;
try {
out = response.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
writer.flush(out, true);
// 关闭writer,释放内存
writer.close();
//此处记得关闭输出Servlet流
IoUtil.close(out);
return true;
}
}
在controller层创建excel文件导出方法,在方法中要创建一个存list的集合如下
ArrayList<List<String>> list = new ArrayList<>();
之后要设置表头代码如下
String[] strs = new String[] { "货物名称", "货物类型""签收人","质量完好","变质数量","破损数量","问题描述","门店地址" };
List<String> strsList= Arrays.asList(strs);//将数组转为集合,用数组转集合是为了更方便清晰,不用使用list一个一个add
list.add(strsList);
而后对查出的数据集合进行处理
1、将查到的数据(purchases)进行循环写入到String数组中,顺序对应表头顺序。
2、将数组转为List存入到大list中
3、至此,数据组装完成可以直接调用工具类
//对数据库的查询方法略
for (int i = 0; i < purchases.size(); i++) {
String[]purstr=new String[]{purchases.get(i).getName(),
purchases.get(i).getType(),
purchases.get(i).getAdduser(),
purchases.get(i).getQuality()==1?"否":"是",
String.valueOf(purchases.get(i).getGobad()),
String.valueOf(purchases.get(i).getDamaged()),
purchases.get(i).getContent(),
purchases.get(i).getStoreaddr()};
List<String> purstrList= Arrays.asList(purstr);
list.add(purstrList);
}
//我的表头和excel文件名是从前端传过来的,所以在这里没写。
ExcelUtils.writerDownLoad(response,request,list,title,excelName);
注意:
1、前台列表可能客户有条件查询的操作,如只想导出2020-01-01至2020-01-31的数据。所以在导出查询的时候,要将前台的查询条件一并传过来进行查询。确保导出的内容与客户查询的内容一致。
2、在调用方法时,不能用ajax异步调用,应该直接访问,会直接调用浏览器对文件进行下载。
3、表头必须先设置存入到大list的0号角标
4、直接访问需要传参可使用代码创建标签模仿点击事件。
操作如下:
前台点击按钮(前台页面框架不一样可能写法不一样,这就是一个单击事件)
js文件中的操作
Purchase.download =function () {
var excelName="进货统计表";
var title="进货统计表";
//将页面所有参数进行拼接传入后台
var url = Feng.ctxPath + "/purchase/download?excelName="+excelName+"&title="+title
+"&name="+$("#name").val()+"&adduser="+$("#adduser").val()+"&quality="+$("#quality").val()
+"&addtime="+$("#addtime").val();
//创建一个a标签,模仿点击事件。
var a = document.createElement('a');
var event = new MouseEvent('click');
a.href = url;
a.dispatchEvent(event);
};
操作结束。如果有帮到你请点个赞吧 ~谢谢