自定义注解实现Execl导入导出
悲伤,我是Java开发程序员,竟然被说是做运维的了。我是开发开发开发!!!!
写个笔记,记录一下以前的execl导入导出功能代码
pom坐标
此处使用常规版本3.9,未使用4.0版本,原因部分API已删除或过时
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAttribute {
/** 对应的列名称 */
String name() default "";
/** 列序号 */
int sort();
/** 字段类型对应的格式 */
String format() default "";
}
导入工具类
public class ExcelImportUtil<T> {
//泛型实体clzz
private Class clazz;
private Field fields[];
public ExcelImportUtil(Class clazz) {
this.clazz = clazz;
fields = clazz.getDeclaredFields();
}
/**
* 基于注解读取excel
*rowIndex 开始行号
*cellIndex开始单元格
*/
public List<T> readExcel(InputStream is, int rowIndex, int cellIndex) {
List<T> list = new ArrayList<T>();
T entity = null;
try {
XSSFWorkbook workbook = new XSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
// 不准确
int rowLength = sheet.getPhysicalNumberOfRows();
// System.out.println(sheet.getLastRowNum());
for (int rowNum = rowIndex; rowNum <= rowLength; rowNum++) {
Row row = sheet.getRow(rowNum);
if (row!=null){
entity = (T) clazz.newInstance();
for (int j = cellIndex; j < row.getPhysicalNumberOfCells(); j++) {
Cell cell = row.getCell(j);
for (Field field : fields) {
if (field.isAnnotationPresent(ExcelAttribute.class)) {
field.setAccessible(true);
ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class);
if (j == ea.sort()) {
field.set(entity, covertAttrType(field, cell));
}
}
}
}
list.add(entity);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 类型转换 将cell 单元格格式转为 字段类型
*/
private Object covertAttrType(Field field, Cell cell) throws Exception {
String fieldType = field.getType().getSimpleName();
if ("String".equals(fieldType)) {
return getValue(cell);
} else if ("Date".equals(fieldType)) {
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(getValue(cell));
} else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
return Integer.parseInt(getValue(cell));
} else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
return Double.parseDouble(getValue(cell));
} else {
return null;
}
}
/**
* 格式转为String
*
* @param cell
* @return
*/
public String getValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
return cell.getRichStringCellValue().getString().trim();
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date dt = DateUtil.getJavaDate(cell.getNumericCellValue());
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(dt);
} else {
// 防止数值变成科学计数法
String strCell = "";
Double num = cell.getNumericCellValue();
BigDecimal bd = new BigDecimal(num.toString());
if (bd != null) {
strCell = bd.toPlainString();
}
// 去除 浮点型 自动加的 .0
if (strCell.endsWith(".0")) {
strCell = strCell.substring(0, strCell.indexOf("."));
}
return strCell;
}
case Cell.CELL_TYPE_BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
default:
return "";
}
}
}
导出工具类
public class ExcelExportUtil<T> {
// 开始行号
private int rowIndex;
//风格索引,使用哪一行最为模板风格
private int styleIndex;
//泛型 实体clzz
private Class clazz;
private Field fields[];
public ExcelExportUtil(Class clazz, int rowIndex, int styleIndex) {
this.clazz = clazz;
this.rowIndex = rowIndex;
this.styleIndex = styleIndex;
fields = clazz.getDeclaredFields();
}
/**
* 基于注解导出
*is execl模板
*objs 数据
*fileName 文件名
*/
public void export(HttpServletResponse response, InputStream is, List<T> objs, String fileName) throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
CellStyle[] styles = getTemplateStyles(sheet.getRow(styleIndex));
AtomicInteger datasAi = new AtomicInteger(rowIndex);
for (T t : objs) {
Row row = sheet.createRow(datasAi.getAndIncrement());
for (int i = 0; i < styles.length; i++) {
Cell cell = row.createCell(i);
cell.setCellStyle(styles[i]);
for (Field field : fields) {
if (field.isAnnotationPresent(ExcelAttribute.class)) {
field.setAccessible(true);
ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class);
if (i == ea.sort()) {
if (field.get(t)==null){
continue;
}
cell.setCellValue(field.get(t).toString());
}
}
}
}
}
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setContentType("application/octet-stream");
response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1")));
response.setHeader("filename", fileName);
workbook.write(response.getOutputStream());
}
public CellStyle[] getTemplateStyles(Row row) {
CellStyle[] styles = new CellStyle[row.getLastCellNum()];
for (int i = 0; i < row.getLastCellNum(); i++) {
styles[i] = row.getCell(i).getCellStyle();
}
return styles;
}
}
使用方法
//导出方法
List<User> data=new ArrayList<User>();
ExcelExportUtil<User> excelExportUtil = new ExcelExportUtil<>(User.class, 1, 0);
ClassPathResource classPathResource = new ClassPathResource("templates/user.xlsx");
try ( InputStream inputStream =classPathResource.getInputStream()) {
excelExportUtil.export(response, data, "导出结果.xlsx");
} catch (Exception e) {
e.printStackTrace();
}
//导入方法
ExcelImportUtil<User> excelUtil = new ExcelImportUtil<User>(User.class);
List<User> userList = excelUtil.readExcel(file.getInputStream(), 1, 0);