前言
之前文章写了个通用的导入Excel摸板,今天把这个导出也补上,大致相差不大,还是基于POI实现。
导入链接:https://blog.csdn.net/weixin_44355855/article/details/108466529
一、代码示例
//注解类
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FileAttributes {
String value();
String defualtValue() default "";
boolean isNull() default true;
Class type() default String.class; //标记特殊类型
}
//导出用户类
public class User {
@FileAttributes(value = "序号",type = Integer.class)
private Integer id;
@FileAttributes(value = "姓名")
private String name;
@FileAttributes(value = "性别")
private String sex;
@FileAttributes(value = "创建日期",type = Date.class)
private Date createDate;
}
/**
*
* @param clazz 导出类
* @param objects 导出数据集
* @param response 响应
* @throws IOException
* @throws IllegalAccessException
*/
public static void export(Class clazz, List<Object> objects,HttpServletResponse response) throws IOException, IllegalAccessException {
XSSFWorkbook workbook = new XSSFWorkbook();
Field[] fields = clazz.getDeclaredFields();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<String> list = new ArrayList<>();
//标题坐标
Map<String,Integer>map=new ConcurrentHashMap<>();
//获取标题
for (int i = 0; i < fields.length; i++) {
FileAttributes annotation = fields[i].getAnnotation(FileAttributes.class);
if (annotation == null) {
continue;
}
list.add(annotation.value());
map.put(annotation.value(),i);
}
XSSFSheet sheet = workbook.createSheet();
XSSFRow row = sheet.createRow(0);
//赋值标头
for (int i = 0; i < list.size(); i++) {
XSSFCell cell = row.createCell(i);
cell.setCellValue(list.get(i));
}
for (int i = 0; i < objects.size(); i++) {
//创建第一行数据
XSSFRow thisRow = sheet.createRow(i+1);
Object o = objects.get(i);
Field[] declaredFields = o.getClass().getDeclaredFields();
//封装填充这一行数据
paddingCell(thisRow,declaredFields,map,o,sdf);
}
//响应
resultResponse(response,workbook);
}
public static void paddingCell(XSSFRow thisRow,Field[] declaredFields,Map<String,Integer>map,Object o,SimpleDateFormat sdf) throws IllegalAccessException {
for (Field field : declaredFields) {
//访问私有值
field.setAccessible(true);
//通过标题map找到对应索引值
FileAttributes annotation = field.getAnnotation(FileAttributes.class);
Integer cellIndex = map.get(annotation.value());
Object value = field.get(o);
XSSFCell cell = thisRow.createCell(cellIndex);
if(annotation.type() == String.class){
cell.setCellValue((String) value);
}else if(annotation.type() == Date.class){
cell.setCellValue(sdf.format((Date) value));
}else if(annotation.type() == Integer.class){
cell.setCellValue((Integer) value);
}
}
}
public static void resultResponse(HttpServletResponse response,XSSFWorkbook workbook) throws IOException {
response.reset();
response.setContentType("application/octet-stream;charset=UTF-8");
SimpleDateFormat newsdf = new SimpleDateFormat("yyyyMMddHHmmss");
String fn = "导出" + newsdf.format(new Date()) + ".xlsx";
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fn,"utf-8"));
response.setHeader("filename",fn);
response.setContentType("application/octet-stream");
response.setCharacterEncoding( "UTF-8");
response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=30");
OutputStream out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
}
写Demo自己测试一下
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/export")
public void export(HttpServletResponse response) throws IOException, IllegalAccessException {
List<Object> list=new ArrayList<>();
Collections.addAll(list,new User(1,"kk","男",new Date()),new User(2,"kk","男",new Date()),new User(3,"kk","男",new Date()),new User(4,"kk","男",new Date()));
ParsingFileUtils.export(User.class,list,response);
}
}