新人博主,随笔记录。主要还是通过自己日常工作积累,系统整理一些技术。希望能够节省更多人的时间,走出自己的路。话不多说
1.使用poi向模板中每行写入excel中的内容(主要是针对表格的复杂样式使用)
2.使用poi通过模板实现excel导出(推荐使用)
官方文档:https://www.yuque.com/easyexcel/doc/easyexcel
之后直接下一步就可以了,创建工程时选择Lombok
进入工程之后,打开Settings(快捷键:Ctrl+Alt+S),安装Lombok插件
需要使用到的jar包(这里我都是用maven注入的)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
工程搭建完成之后。开始实现EasyExcel使用模板导出
创建导出实体:
/**
* 学生
*/
@Data
public class Student extends BaseRowModel {
/**
* 姓名
*/
@ExcelProperty(value = "姓名",index = 0)
private String name;
/**
* 年龄
*/
@ExcelProperty(value = "年龄",index = 1)
private int age;
/**
* 性别
*/
@ExcelProperty(value="性别",index = 2)
@ExcelIgnore
private String sex;
/**
* 学号
*/
@ExcelProperty(value="学号",index = 3)
private long num;
/**
* 家庭地址
*/
@ExcelProperty(value = "家庭地址",index = 4)
private String address;
}
这个实体首先要继承BaseModel
实体中的注解,我在这简单说明一下,具体上面的官方文档都有。可以自己查找
@Data :Lombok的注解,里面包含了所有参数的set和get方法
@ExcelProperty注解:
@ExcelIgnore : 默认所有字段都会和excel去匹配,加了这个注解会忽略该字段
ExportExcelDemo
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* 使用easyExcel导出excel
*/
@RestController
public class ExportExcelDemo {
/**
* 使用EasyExcel模板导出excel
* @param response
* @param session
* @throws Exception
*/
@GetMapping(value = "/exportExcelByTemplate")
public void exportExcelByTemplate(HttpServletResponse response, HttpSession session) throws Exception {
response.setContentType("multipart/form-data");
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream;charset=utf-8");
LocalDate time = LocalDate.now();
String fileName = URLDecoder.decode("easyExcel导出模板_" + time, "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("gb2312"), "ISO8859-1") + ".xls" + "\"");
OutputStream out = response.getOutputStream();
List<Student> data = getData();
//根据模板导出数excel
ExcelUtil.exportTemplate("templates/template.xls", "model.xls", out, Student.class,ExportExcelDemo.class, data, session);
}
//封装导出数据
private List<Student> getData() {
List<Student> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Student student = new Student();
student.setName("测试学生姓名-" + i);
student.setAge(i);
student.setSex(i % 2 == 1 ? "男" : "女");
student.setNum(111111L);
student.setAddress("追晨始梦CSDN博客");
list.add(student);
}
return list;
}
}
ExcelUtil :工具类
package com.example.demo;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.List;
import java.util.Map;
/**
* Description: Excel操作工具类
*/
@Slf4j
public class ExcelUtil {
/**
* 根据模板导出excel
*
* 支持简易循环填写excel
*
* @param templatePath 模板路径
* @param temporaryName 临时文件名称
* @param out 文件输出流
* @param head easyPoi 表头对象class
* @param list 填充列表
* @param col 导出类class
* @param session session
*/
public static void exportTemplate(String templatePath, String temporaryName, OutputStream out, Class head, Class col, List<? extends BaseRowModel> list, HttpSession session) {
String path = null;
try {
InputStream resourceAsStream = col.getClassLoader().getResourceAsStream(templatePath);
path = ExcelUtil.getFilePath(temporaryName, resourceAsStream, session);
EasyExcel.write(out, head).needHead(false).withTemplate(path).sheet().doWrite(list);
} catch (IOException e) {
e.printStackTrace();
} finally {//删除临时文件
if (path!=null && !"".equals(path)) {
File tempFile = new File(path);
tempFile.delete();
System.err.println("删除临时文件成功=====path:" + path);
}
}
}
/**
* 获取临时文件路径
*
* @param inputStream
* @param session
* @param fileName
* @return
* @throws IOException
*/
public static String getFilePath(String fileName, InputStream inputStream, HttpSession session) throws IOException {
// 模板临时目录
String rootPath = session.getServletContext().getRealPath("template/");
// 临时文件路径名
String filePath = rootPath + "_" + System.currentTimeMillis() + fileName;
File tempFile = new File(filePath);
// 保存到临时文件
saveTempFile(inputStream, tempFile);
return filePath;
}
// 保存到临时目录
private static void saveTempFile(InputStream inputStream, File tempFile) throws IOException {
if (!tempFile.getParentFile().exists()) { //如果文件的目录不存在
tempFile.getParentFile().mkdirs(); //创建目录
}
OutputStream os = new FileOutputStream(tempFile);
byte[] b = new byte[2048];
int length;
while ((length = inputStream.read(b)) > 0) {
os.write(b, 0, length);
}
os.flush();
os.close();
inputStream.close();
}
}
获取到静态资源中模板文件路径的问题;
因为EasyExcel,不支持流的方式读取模板文件,所以我们必须要用路径的方式去获取路径。在本地运行时,使用相对路径或者绝对路径获取模板路径是可以的。但是当工程打成jar包之后,获取的路径无法支持。
所以我们这里使用的方案:通过流获取模板文件,重新写到本地临时文件中,获取模板,使用完模板之后,再将模板删除。
源码链接
官方文档地址