导入POI相关坐标依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
创建自定义注解类
ExportExcelTitle
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExportExcelTitle {
int length();
String description();
}
ExportExcelField
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExportExcelField {
int index();
String description();
}
ImportExcelField
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ImportExcelField {
int index();
}
创建相关实体类信息,并在需要导入导出的属性上面使用自定义的注解
import com.anhk.annotation.ExportExcelField;
import com.anhk.annotation.ExportExcelTitle;
import com.anhk.annotation.ImportExcelField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@TableName("db_user")
@ExportExcelTitle(length = 4, description = "用户信息")
public class User {
@TableId(type = IdType.UUID)
private String id;
@ImportExcelField(index = 0)
@ExportExcelField(index = 0, description = "用户名")
private String userName;
@ImportExcelField(index = 1)
private String password;
@ImportExcelField(index = 2)
@ExportExcelField(index = 1, description = "联系方式")
private String mobile;
@ImportExcelField(index = 3)
@ExportExcelField(index = 2, description = "邮箱")
private String mail;
@ImportExcelField(index = 4)
@ExportExcelField(index = 3, description = "住址")
private String address;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public User() {
}
public User(String id, String userName, String password, String mobile, String mail, String address) {
this.id = id;
this.userName = userName;
this.password = password;
this.mobile = mobile;
this.mail = mail;
this.address = address;
}
}
创建导入导出相关API接口
import com.anhk.exception.CustomerException;
import com.anhk.exception.ExceptionEnum;
import com.anhk.pojo.User;
import com.anhk.service.UserService;
import com.anhk.utils.ExcelUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/exportUserToExcel")
public ResponseEntity<Void> exportUserToExcel(HttpServletRequest request, HttpServletResponse response, String userName) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(userName)) {
queryWrapper.lambda().like(User::getUserName, userName);
}
List<User> userList = userService.list(queryWrapper);
ExcelUtils.exportDataToExcel(request, response, userList, User.class);
return ResponseEntity.ok().build();
}
@PostMapping("/importUserFromExcel")
@Transactional(rollbackFor = Exception.class)
public ResponseEntity<Void> importUserFromExcel(MultipartFile file) {
InputStream inputStream = null;
try {
String filename = file.getOriginalFilename();
inputStream = file.getInputStream();
List<User> userList = ExcelUtils.importDataFromExcel(inputStream, filename, User.class);
boolean saveBatch = userService.saveBatch(userList);
if (!saveBatch) {
throw new CustomerException(ExceptionEnum.IMPORT_DATA_ERROR);
}
} catch (CustomerException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new CustomerException(ExceptionEnum.IMPORT_DATA_ERROR);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return ResponseEntity.ok().build();
}
}
创建导入导出相关工具类
import com.anhk.annotation.ExportExcelField;
import com.anhk.annotation.ExportExcelTitle;
import com.anhk.annotation.ImportExcelField;
import com.anhk.exception.CustomerException;
import com.anhk.exception.ExceptionEnum;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ExcelUtils {
private static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
public static <T> void exportDataToExcel(HttpServletRequest request, HttpServletResponse response, List<T> dataList, Class<T> clazz) {
Workbook workbook = new SXSSFWorkbook();
ByteArrayOutputStream byteArrayOutputStream = null;
try {
ExportExcelTitle exportExcelTitle = clazz.getAnnotation(ExportExcelTitle.class);
if (exportExcelTitle == null) {
throw new CustomerException(ExceptionEnum.CAN_NOT_EXPORT_THIS_TYPE_DATA);
}
Sheet sheet = workbook.createSheet(exportExcelTitle.description());
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue(exportExcelTitle.description());
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, exportExcelTitle.length() - 1));
row = sheet.createRow(1);
ArrayList<Field> fields = new ArrayList<>();
Field[] filedArr = clazz.getDeclaredFields();
for (Field field : filedArr) {
ExportExcelField exportExcelField = field.getAnnotation(ExportExcelField.class);
if (exportExcelField != null) {
cell = row.createCell(exportExcelField.index());
cell.setCellValue(exportExcelField.description());
fields.add(field);
}
}
int rowNum = 2;
for (T t : dataList) {
row = sheet.createRow(rowNum++);
for (Field field : fields) {
ExportExcelField ExportExcelField = field.getAnnotation(ExportExcelField.class);
String fieldName = field.getName();
String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Method method = clazz.getDeclaredMethod(methodName);
Object cellValue = method.invoke(t);
cell = row.createCell(ExportExcelField.index());
setCellValue(workbook, cell, cellValue);
}
}
byteArrayOutputStream = new ByteArrayOutputStream();
workbook.write(byteArrayOutputStream);
DownLoadUtil.download(byteArrayOutputStream, exportExcelTitle.description() + ".xlsx", request, response);
} catch (CustomerException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new CustomerException(ExceptionEnum.EXPORT_DATA_ERROR);
} finally {
if (byteArrayOutputStream != null) {
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static <T> List<T> importDataFromExcel(InputStream inputStream, String fileName, Class<T> clazz) {
if (inputStream == null) {
return null;
}
Workbook workbook = null;
ArrayList<T> dataList = null;
try {
String suffix = fileName.substring(fileName.lastIndexOf("."));
if (".xlsx".equals(suffix)) {
workbook = new XSSFWorkbook(inputStream);
} else if (".xls".equals(suffix)) {
workbook = new HSSFWorkbook(inputStream);
} else {
throw new CustomerException(ExceptionEnum.IMPORT_FILE_TYPE_ERROR);
}
Sheet sheet = workbook.getSheetAt(0);
if (sheet == null) {
throw new CustomerException(ExceptionEnum.FILE_DATA_ERROR);
}
int lastRowNum = sheet.getLastRowNum();
dataList = new ArrayList<>(lastRowNum);
Field[] fieldArr = clazz.getDeclaredFields();
Row row = null;
Cell cell = null;
for (int i = 1; i < lastRowNum; i++) {
row = sheet.getRow(i);
T t = clazz.newInstance();
for (Field field : fieldArr) {
ImportExcelField importExcelField = field.getAnnotation(ImportExcelField.class);
if (importExcelField != null) {
cell = row.getCell(importExcelField.index());
field.setAccessible(true);
if (field.getType() == Integer.class) {
int intVal = (int) Math.round(cell.getNumericCellValue());
if (Double.parseDouble(intVal + ".0") == cell.getNumericCellValue()) {
field.set(t, intVal);
}
} else if (field.getType() == Double.class) {
field.set(t, cell.getNumericCellValue());
} else if (field.getType() == Long.class) {
long longVal = Math.round(cell.getNumericCellValue());
field.set(t, longVal);
} else if (field.getType() == Boolean.class) {
field.set(t, cell.getBooleanCellValue());
} else if (field.getType() == Date.class) {
field.set(t, cell.getDateCellValue());
} else {
field.set(t, cell.getStringCellValue());
}
}
}
dataList.add(t);
}
} catch (CustomerException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new CustomerException(ExceptionEnum.IMPORT_DATA_ERROR);
} finally {
if (workbook != null) {
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return dataList;
}
public static void setCellValue(Workbook workbook, Cell cell, Object fieldVal) {
DecimalFormat df = new DecimalFormat("######0.000");
if (fieldVal instanceof Date) {
DataFormat dataFormat = workbook.createDataFormat();
CellStyle cellStyle = text(workbook);
cellStyle.setDataFormat(dataFormat.getFormat("yyyy-MM-dd HH:mm:ss"));
cell.setCellStyle(cellStyle);
cell.setCellValue((Date) fieldVal);
} else if (fieldVal instanceof Integer) {
int intVal = (Integer) fieldVal;
cell.setCellValue(intVal);
cell.setCellStyle(text(workbook));
} else if (fieldVal instanceof Float) {
Float fVal = (Float) fieldVal;
BigDecimal b1 = new BigDecimal(df.format(fVal) + "");
cell.setCellValue(
Float.parseFloat(String.valueOf(b1).substring(0, String.valueOf(b1).indexOf(".") + 3)));
cell.setCellStyle(text(workbook));
} else if (fieldVal instanceof Double) {
double dVal = (Double) fieldVal;
BigDecimal b1 = new BigDecimal(df.format(dVal) + "");
cell.setCellValue(Double
.parseDouble(String.valueOf(b1).substring(0, String.valueOf(b1).indexOf(".") + 3)));
cell.setCellStyle(text(workbook));
} else if (fieldVal instanceof Long) {
long longValue = (Long) fieldVal;
cell.setCellValue(longValue);
cell.setCellStyle(text(workbook));
} else {
if (fieldVal != null) {
cell.setCellValue(fieldVal.toString());
} else {
cell.setCellValue("");
}
cell.setCellStyle(text(workbook));
}
}
public static CellStyle bigTitle(Workbook wb) {
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 16);
font.setBold(true);
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
return style;
}
public static CellStyle title(Workbook wb) {
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("黑体");
font.setFontHeightInPoints((short) 14);
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
return style;
}
public static CellStyle text(Workbook wb) {
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("等线");
font.setFontHeightInPoints((short) 12);
style.setFont(font);
style.setAlignment(HorizontalAlignment.LEFT);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
return style;
}
}
创建下载工具类
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class DownLoadUtil {
public static void download(ByteArrayOutputStream byteArrayOutputStream, String returnName, HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/octet-stream;charset=utf-8");
request.setCharacterEncoding("UTF-8");
String header = request.getHeader("User-Agent").toUpperCase();
if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
returnName = URLEncoder.encode(returnName, "utf-8");
returnName = returnName.replace("+", "%20");
} else {
returnName = new String(returnName.getBytes(), "ISO8859-1");
}
response.addHeader("Content-Disposition", "attachment;filename=\"" + returnName + "\"");
response.setContentLength(byteArrayOutputStream.size());
ServletOutputStream outputStream = response.getOutputStream();
byteArrayOutputStream.writeTo(outputStream);
byteArrayOutputStream.close();
outputStream.flush();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~