一、前言
Java开发中,常见的导入/导出插件是EasyPoi,简单易学,功能强大。如果我们希望导出的文件有复杂的样式的时,使用EasyPoi的POJO类处理显然就力不从心,因此就得使用EasyPoi模板。由于项目部署环境和打包框架等问题,代码中获取EasyPoi模板比较困难且容易导致NPE。因此,可以使用FreeMarker模板来做替换,该方法生成文件时只需要传入文档流即可。
FreeMarker模板的制作,不在本篇博客讨论。见本人另一篇博客:
https://blog.csdn.net/qq_41057885/article/details/109686568
二、导出功能实现
1. Controller层实现
@GetMapping("aaa/bbb/ccc")
@ResponseBody
public void excelOut(Integer id) {
Map data = service.selectOneById(id);
// 获取模板文件
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("static/excel/temp.ftl");
try {
// 生成导出文档
File file = FreeMarkerUtils.createFile(inputStream, data);
// 此处可以填写xls(excel)或者doc(word),主要看是什么类型FreeMarker模板
FreeMarkerUtils.downWord(response, file, "报表", "xls");
} catch (IOException e) {
e.printStackTrace();
}
}
2. FreeMarkerUtils工具类
public class FreeMarkerUtils {
/**
* 创建文档
*/
public static File createFile(InputStream tempStream, Map dataMap) throws IOException {
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
String fileName = UUID.randomUUID().toString().replaceAll("-", "");
File file = new File(fileName);
try {
Template template = new Template(fileName, new InputStreamReader(tempStream), configuration);
Writer w = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
template.process(dataMap, w);
w.close();
} catch (Exception e) {
e.printStackTrace();
throw new IOException("创建文档出错");
}
return file;
}
/**
* 客户端下载文档
*/
public static void downWord(HttpServletResponse response, File file, String fileName, String fileType) throws IOException {
// 设置浏览器以下载的方式处理该文件的文件名,支持中文
setFileDownloadHeader(response, fileName, "." + fileType);
InputStream fin = null;
ServletOutputStream out = null;
try {
// 调用工具类WordGenerator的createDoc方法生成Word文档
fin = new FileInputStream(file);
out = response.getOutputStream();
byte[] buffer = new byte[1024];
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while ((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} catch (Exception e) {
e.printStackTrace();
throw new IOException("下载文件出错");
} finally {
if (fin != null) {
fin.close();
}
if (out != null) {
out.close();
}
if (file != null) {
// 删除临时文件
file.delete();
}
}
}
/**
* 设置让浏览器弹出下载对话框的Header
*/
public static void setFileDownloadHeader(HttpServletResponse response, String fileName, String fileType) {
try {
// 中文文件名支持
String encodedfileName = new String(fileName.getBytes("GBK"), "ISO8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName + fileType + "\"");
response.setCharacterEncoding("utf-8");
switch (fileType) {
case ".doc":
response.setContentType("application/msword");
break;
case ".docx":
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
break;
case ".xls":
response.setContentType("application/ms-excel");
break;
case ".xlsx":
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
break;
default:
break;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
3. 前端导出功能代码
<!--HTML代码-->
<button type="button" id="excelOutBtn" class="btn btn-sm bg-orange">
<i class="fa fa-cloud-upload fa-btn"></i> 导出
</button>
<!--JS-->
// 导出
$("#excelOutBtn").click(function () {
window.location.href = "${basePath}/aaa/bbb/ccc?id=" + $("#id").val();
});