前面的项目一直用的是easypoi来进行excel的上传下载,最近发现阿里的EasyExcel更好用,在这里分享一下,具体的可以在官网探索。
官网入口: 点击进入
一、添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
二、测试代码准备
首先需要编写一个 数据接收类 、 excel对应类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String id;
private String name;
private String realName;
private String sexName;
}
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class UserExcel {
// index 会影响excel数据排列顺序
@ExcelProperty(value = "编号",index = 1)
private String id;
@ExcelProperty(value = "别名",index = 2)
private String name;
@ExcelProperty(value = "名称",index = 4)
private String realName;
@ExcelProperty(value = "性别",index = 3)
private String sexName;
}
三、示例代码
3.1 写文件
将数据信息写入 Excel 中:
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import pojo.StartApplication;
import pojo.User;
import pojo.UserExcel;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(classes= StartApplication.class)
@RunWith(SpringRunner.class)
public class TestDemo1 {
private List<User> users = new ArrayList<>();
@Before
public void before(){
users.add(new User("1","xj1","bunana","1"));
users.add(new User("2","xj2","bunana","2"));
users.add(new User("3","xj3","bunana","1"));
users.add(new User("4","xj4","bunana","1"));
}
/**
* 将数据写入excel
* @throws Exception
*/
@Test
public void testWrite() throws Exception {
File file = new File("/test/test_w.xlsx");
// 针对文件路径,获取文件所在路径之上的路径信息
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
// 判断文件是否存在
if(!file.exists()){
file.createNewFile();
}
EasyExcel.write(file, UserExcel.class).sheet("test").doWrite(users);
}
}
运行测试:
3.2 读文件
由于没有excel文件,所以先说的写操作。接下来将写的excel再解析出来。
@Test
public void testRead() throws Exception {
File file = new File("/test/test_w.xlsx");
// 针对文件路径,获取文件所在路径之上的路径信息
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
// 判断文件是否存在
if(!file.exists()){
file.createNewFile();
}
InputStream inputStream = new FileInputStream(file);
EasyExcel.read(inputStream,UserExcel.class,new AnalysisEventListener<UserExcel>(){
// 解析每条数据时触发
@Override
public void invoke(UserExcel userExcel, AnalysisContext analysisContext) {
// 如果是需要将数据解析存数据库,建议放集合中再存,不要有一条就存一次
System.out.println(userExcel);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//System.out.println(analysisContext);
}
// 获取表头数据信息
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println(headMap);
}
}).sheet("test").doRead();
}
四、注意事项
4.1 监听器的区别
本次读操作,采取read(InputStream inputStream, Class head, ReadListener readListener),配置有数据对应映射处理类。
如果使用read(InputStream inputStream, ReadListener readListener)
此时监听器invoke(Object 0, AnalysisContext analysisContext)中的Object 是一个linkedhashmap数据类型!
4.2 关于UserExcel映射类
属性上增加注解@ExcelProperty可以对数据信息进行配置,这里需要强调一点,index值是从 0 开始算的!!
本次这里配置为:
则让生成excel文件出现前面空列的问题:
其次index值,影响字段在excel表中的顺序!
五、关于web的上传和下载
由于上面的读写操作,采取将数据流信息写入文件操作,如果涉及到文件的上传和下载操作,可以直接将流信息填充。如下测试案例所示。
示例代码:
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@Api(value = "EasyExcel文件上传和下载测试类")
@RestController
public class FileUploadAndDownController {
@ApiOperation(value = "Excel文件上传数据解析",notes = "test2")
@PostMapping("/upload")
public void upload(MultipartFile file) throws IOException {
ArrayList<UserExcel> userExcels = new ArrayList<>();
EasyExcel.read(file.getInputStream(),UserExcel.class,new AnalysisEventListener<UserExcel>(){
@Override
public void invoke(UserExcel userExcel, AnalysisContext analysisContext) {
System.out.println("解析数据:"+userExcel);
userExcels.add(userExcel);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}).sheet("test").doRead();
userExcels.forEach(e->{
System.out.println("存数据库!");
System.out.println(e);
});
}
@ApiOperation(value = "Excel文件下载",notes = "test2")
@GetMapping("download")
public void download(HttpServletResponse response) throws Exception {
List<User> users = new ArrayList<>();
users.add(new User("1","xj1","bunana","1"));
users.add(new User("2","xj2","bunana","2"));
users.add(new User("3","xj3","bunana","1"));
users.add(new User("4","xj4","bunana","1"));
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("测试", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
// 绕过了创建临时文件,直接将数据读到流中传递至客户端
EasyExcel.write(response.getOutputStream(), UserExcel.class).sheet("test").doWrite(users);
}
}
上传测试:
下载测试:
链接:http://localhost/download
六、文件上传到七牛云
有时候我们需要将生成的文件永久性存储,放在服务器显然不合适,可以上传到七牛云。
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.bdysoft.cloud.OSSFactory;
import com.bdysoft.common.dto.UploadResultDto;
import java.io.ByteArrayOutputStream;
import java.util.List;
/**
* EasyExcel生成文件并上传七牛云
*
* @author lvwei
*/
public class EasyExcelUploadUtil {
public static UploadResultDto uploadExcel(Integer storeId, Class<?> obj, List<?> list, String sheetName) {
//字节流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
EasyExcel.write(bos, obj)
.excelType(ExcelTypeEnum.XLSX)
.sheet(sheetName)
.doWrite(list);
// 调用七牛云的上传方法,上传成功,七牛云会将地址返回
UploadResultDto resultDto = OSSFactory.build(storeId).uploadSuffix(bos.toByteArray(), ExcelTypeEnum.XLSX.getValue());
resultDto.setFileSize(Long.parseLong(bos.size() + ""));
return resultDto;
}
}
评论 (0)