早期Java使用的一些解析,到处excel的框架存在种种问题被遗弃,现在使用阿里巴巴所提供的EasyExcel已成为一种主流,本篇将详细介绍该功能在Web项目中如何实际应用。
详细操作文档:写Excel | Easy Excel
一、项目演示
在后台管理界面中,使用Excel到处表格的功能较为常见,如下所示:
1.1 引入Maven依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency>
1.2 观察Demo
可以看出,该步骤其实主要分为以下四步:
- 设置下载文件的请求头
- 获取需要导出的数据
- 把数据写入Excel中
- 如果出现异常需要返回对应的Json字符串
主要代码预览:
1.3 设置下载文件的请求头
这里我们是通过自己实现的WebUtil工具类来实现设置下载文件的请求头,其实跟给出的Demo没什么区别,只是做了一层封装。
1.4 获取需要导出的数据
这里利用mp提供的list方法查询出来需要导出的数据,暂且存入到 categoryVos中,但是由于Category中的属性过多,所以我们这里创建了一个ExcelCategoryVo的对象用来存储,
注意这个对象需要添加上相应的注解才行:
后续,我们通过自己实现的Bean拷贝的工具类,将原先不符合条件的类转为符合条件的类,也就是上面我们展示的ExcelCategoryVo类,工具类如下:
package com.fox.utils;import org.springframework.beans.BeanUtils;import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;public class BeanCopyUtils {private BeanCopyUtils() {}public static <T> T copyBean(Object source,Class<T> clazz) {//创建目标对象T result = null;try {result = clazz.newInstance();//实现属性copyBeanUtils.copyProperties(source, result);} catch (Exception e) {e.printStackTrace();}//返回结果return result;}public static <E,T> List<T> copyBeanList(List<E> list, Class<T> clazz){
// List<T> result = new ArrayList<>();
// for (E e : list) {
// T t = copyBean(e, clazz);
// result.add(t);
// }
// return result;return list.stream().map(E -> copyBean(E, clazz)).collect(Collectors.toList());}
}
1.5 把数据写入Excel中
观察Demo,大致是需要修改这三处地方:
DownloadData也就是我们实际需要存储到Excel中的对象:
sheet大致我们可以从英文字符中得出,他应该就是Excel中表的名字:
利用Ctrl+P,根据idea的提示,doWrite方法可以传入Collection的实现类,观察Demo中的data()方法其实是返回一个list集合,里面存储的是写入的对象
那么我们也可以返回一个list集合:
1.6 返回异常信息
ResponseResult是我自定义的统一格式响应体:
可能有人会问,为什么这个方法的返回值是空呢? 而不是一般项目要求的统一格式返回体呢?
这是因为这里根据EasyExcel的Demo中所演示的,该方法其实已经将文件信息写入Json字符串中返回去了,如果这个时候再设置返回一个ResponseResult(自定义的统一格式返回体),那么浏览器就无法解析这个响应到底是哪个了,所以这里设置这个方法的返回值为void,也就是空。
运行程序,响应成功:
下载成功后的Excel展示:
1.7 最终代码展示:
controller层:
package com.fox.contrller;import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.fox.domain.ResponseResult;
import com.fox.domain.entity.Category;
import com.fox.domain.vo.CategoryVo;
import com.fox.domain.vo.ExcelCategoryVo;
import com.fox.enums.AppHttpCodeEnum;
import com.fox.service.CategoryService;
import com.fox.utils.BeanCopyUtils;
import com.fox.utils.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.List;@RestController
@RequestMapping("/content/category")
public class CategoryController {@Autowiredprivate CategoryService categoryService;@GetMapping("/export")public void export(HttpServletResponse response) {try {//设置下载文件的请求头WebUtils.setDownLoadHeader("分类.xlsx",response);//获取需要导出的数据List<Category> categoryVos = categoryService.list();List<ExcelCategoryVo> excelCategoryVos = BeanCopyUtils.copyBeanList(categoryVos, ExcelCategoryVo.class);//把数据写入到Excel中EasyExcel.write(response.getOutputStream(), ExcelCategoryVo.class).autoCloseStream(Boolean.FALSE).sheet("分类导出").doWrite(excelCategoryVos);} catch (Exception e) {//如果出现异常也要响应JsonResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);WebUtils.renderString(response, JSON.toJSONString(result));}}
}
WebUtil工具类:
package com.fox.utils;import org.springframework.web.context.request.RequestContextHolder;import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;public class WebUtils
{/*** 将字符串渲染到客户端* * @param response 渲染对象* @param string 待渲染的字符串* @return null*/public static void renderString(HttpServletResponse response, String string) {try{response.setStatus(200);response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().print(string);}catch (IOException e){e.printStackTrace();}}public static void setDownLoadHeader(String filename, HttpServletResponse response) throws UnsupportedEncodingException {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");String fname= URLEncoder.encode(filename,"UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition","attachment; filename="+fname);}
}
Bean拷贝工具类
package com.fox.utils;import org.springframework.beans.BeanUtils;import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;public class BeanCopyUtils {private BeanCopyUtils() {}public static <T> T copyBean(Object source,Class<T> clazz) {//创建目标对象T result = null;try {result = clazz.newInstance();//实现属性copyBeanUtils.copyProperties(source, result);} catch (Exception e) {e.printStackTrace();}//返回结果return result;}public static <E,T> List<T> copyBeanList(List<E> list, Class<T> clazz){
// List<T> result = new ArrayList<>();
// for (E e : list) {
// T t = copyBean(e, clazz);
// result.add(t);
// }
// return result;return list.stream().map(E -> copyBean(E, clazz)).collect(Collectors.toList());}
}