依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<!-- poi对于excel 2007的支持依赖-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<!-- poi对于excel 2007的支持依赖-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
导出注解声明
/**
* @author adminUser
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excel {
}
导出字段声明
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelValue {
String value() default "";
}
通过AOP执行逻辑代码 利用反射获取对象的值和表头表体
@Aspect
@Component
public class ExcelAop {
@Autowired
HttpServletRequest request;
@Pointcut("@annotation(com.annotation.annotation.annotation.Excel)")
public void excel(){
}
@Around(value = "excel()")
public Object around(ProceedingJoinPoint joinPoint){
try {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletResponse response = requestAttributes.getResponse();
Object[] args = joinPoint.getArgs();
Workbook work = new XSSFWorkbook();
Sheet sheet = work.createSheet();
Integer rowInt = 1;
Row row = sheet.createRow(0);
Map<Object,Integer> objHearder = new HashMap<>();
for (Object arg : args) {
if (arg instanceof Collection){
List<Object> argList = (List<Object>) arg;
for (Object o : argList) {
Field[] declaredFields = o.getClass().getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
//设置Excel表头
ExcelValue annotation = declaredFields[i].getAnnotation(ExcelValue.class);
Cell cell = row.createCell(i);
cell.setCellValue(annotation.value());
objHearder.put(annotation.value(),i);
}
Row sheetRow = sheet.createRow(rowInt++);
for (Field declaredField : declaredFields) {
ExcelValue annotation = declaredField.getAnnotation(ExcelValue.class);
Cell cell = sheetRow.createCell(objHearder.get(annotation.value()));
declaredField.setAccessible(true);
cell.setCellValue(declaredField.get(o).toString());
}
}
}else {
throw new RuntimeException("当前仅支持集合类型");
}
ByteArrayOutputStream os=new ByteArrayOutputStream();
work.write(os);
String fileName = "导出文件名-"+System.currentTimeMillis()+ ".xlsx";
download(os,response,fileName);
}
return null;
}catch (Exception e){
e.printStackTrace();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException, IOException {
response.setContentType("application/octet-stream");
returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1"));
response.addHeader("Content-Disposition","attachment;filename="+returnName);
response.setContentLength(byteArrayOutputStream.size());
response.addHeader("Content-Length", "" + byteArrayOutputStream.size());
ServletOutputStream outputStream = response.getOutputStream();
byteArrayOutputStream.writeTo(outputStream);
byteArrayOutputStream.close();
outputStream.flush();
}
}
声明实体
package com.annotation.annotation.po;
import com.annotation.annotation.annotation.ExcelValue;
public class User {
@ExcelValue("用户名")
private String userName;
@ExcelValue("密码")
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
测试类
@Excel
@PostMapping("/testExcel")
public String testExcel(@RequestBody List<User> user){
return user.toString();
}
执行效果
可以在环绕通知当中获取返回值更改代码进行导出,博主是通过传参进行的导出