1、引入依赖
org.apache.poi
poi
4.0.1
org.apache.poi
poi-ooxml
4.0.1
com.monitorjbl
xlsx-streamer
2.1.0
2、编写ExcelDataDO类
@Data
public class ExcelDataDO {
public Class clazz;
public ExcelData(Class clazz) {
this.clazz = clazz;
}
public String sheetName;
public List data;
}
3、编写自动封装@ExcelField注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.FIELD})
public @interface ExcelField {
/**
* 导出到Excel中的名字.
*/
public abstract String name();
/**
* 配置列的名称,对应A,B,C,D....
*/
public abstract String column();
/**
* 必填项
*/
public abstract boolean required() default false;
/**
* 校验规则(正则)
*/
public abstract String regex() default "";
/**
* 是否导出数据
*/
public abstract boolean isExport() default true;
}
4、编写自动封装@ExcelHeaderField注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.FIELD})
public @interface ExcelHeaderField {
/**
* 导出到Excel中的名字.
*/
public abstract String name();
/**
* 配置列的名称,对应A,B,C,D....
*/
public abstract String column();
/**
* 配置所在行索引
*/
public abstract int row();
/**
* 配置所在行合
*/
public abstract String rowMerge() default "";
/**
* 是否导出数据
*/
public abstract boolean isExport() default true;
}
5、编写自动封装ExcelChannerDO实体类
@Data
public class ExcelChannerDO{
private int sheetIndex = 0;
private int headRow = 2;
@ExcelHeaderField(name = "附表2-4:XX市建制村通达路径表", column = "A", row = 1, rowMerge = "N")
private String fileName="附表2-4:XX市建制村通达路径表";
/**
* 序号
*/
@ExcelField(name = "序号", column = "A", required = true)
@ExcelHeaderField(name = "序号", column = "A", row = 2)
private String serialNo;
/**
* 村编码
*/
@ExcelField(name = "村名称", column = "B", required = true)
@ExcelHeaderField(name = "村名称", column = "B", row = 2)
private String countryCode;
/**
* 村名称
*/
@ExcelField(name = "村名称", column = "C", required = true)
@ExcelHeaderField(name = "村名称", column = "C", row = 2)
private String countryName;
/**
* 路径序号
*/
@ExcelField(name = "路径序号", column = "D", required = true)
@ExcelHeaderField(name = "路径序号", column = "D", row = 2)
private String roadSerialNo;
/**
* 路径中路线名称
*/
@ExcelField(name = "路线名称", column = "E", required = true)
@ExcelHeaderField(name = "路线名称", column = "E", row = 2)
private String roadName;
/**
* 路径中路线代码
*/
@ExcelField(name = "路线代码", column = "F", required = true)
@ExcelHeaderField(name = "路线代码", column = "F", row = 2)
private String roadCode;
/**
* 基础路线id
*/
private String basicRoadId;
/**
* 路线在路径中的起点桩号
*/
@ExcelField(name = "路线在路径中的起点桩号", column = "G", required = true)
@ExcelHeaderField(name = "路线在路径中的起点桩号", column = "G", row = 2)
private BigDecimal startPointSectionNo;
/**
* 路线在路径中的止点桩号
*/
@ExcelField(name = "路线在路径中的止点桩号", column = "H", required = true)
@ExcelHeaderField(name = "路线在路径中的止点桩号", column = "H", row = 2)
private BigDecimal endPointSectionNo;
/**
* 技术等级
*/
@ExcelField(name = "技术等级", column = "J", required = true)
@ExcelHeaderField(name = "技术等级", column = "J", row = 2)
private String technicalGrade;
/**
* 市编码
*/
private String cityCode;
/**
* 市名称
*/
@ExcelField(name = "市名称", column = "K", required = true)
@ExcelHeaderField(name = "市名称", column = "K", row = 2)
private String cityName;
/**
* 县编码
*/
private String countyCode;
/**
* 县名称
*/
@ExcelField(name = "县名称", column = "L", required = true)
@ExcelHeaderField(name = "县名称", column = "L", row = 2)
private String countyName;/**
* 乡镇编码
*/
private String villageCode;
/**
* 乡镇名称
*/
@ExcelField(name = "乡镇名称", column = "M", required = true)
@ExcelHeaderField(name = "乡镇名称", column = "M", row = 2)
private String villageName;
/**
* 备注
*/
@ExcelField(name = "备注", column = "N", required = true)
@ExcelHeaderField(name = "备注", column = "N", row = 2)
private String remark;
}
6、编写ExcelUtil类
/**
* Excel 工具类.
*/
@SuppressWarnings("all")
public class ExcelUtil {
public Class clazz;
boolean v2007 = true;
private Workbook workbook;
public ExcelUtil(Class clazz) {
this.clazz = clazz;
}
public Workbook getWorkbook(InputStream in, boolean v2007) throws Exception {
Workbook workbook = null;
this.v2007 = v2007;
if (v2007) {
workbook = StreamingReader.builder().rowCacheSize(1000).bufferSize(4096).open(in);
} else {
workbook = new HSSFWorkbook(in);
}
return workbook;
}
public boolean validity(Workbook workbook) throws Exception {
Sheet sheet = workbook.getSheetAt(0);
List allFields = getMappedFiled(clazz, null);
if (sheet.getLastRowNum() <= 0) {
return false;
}
Row topRow = null;
boolean flag = false;
for (Row row : sheet) {
if (flag) {
break;
}
topRow = row;
flag = true;
}
int colNum = 0;
for (Field field : allFields) {
if (field.isAnnotationPresent(ExcelField.class)) {
ExcelField attr = field.getAnnotation(ExcelField.class);
if (topRow.getCell(colNum) == null) {
return false;
} else {
String headName = topRow.getCell(colNum).getStringCellValue();
if (!headName.equals(attr.name())) {
return false;
}
}
colNum++;
}
}
return true;
}
public List> getList(Workbook workbook, int headRow) throws Exception {
List> result = new ArrayList>();
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
Sheet sheet = workbook.getSheetAt(i);
ExcelDataDO exceData = new ExcelDataDO(clazz);
List list = getList(sheet, headRow);
exceData.setSheetName(sheet.getSheetName());
exceData.setData(list);
result.add(exceData);
}
return result;
}
public List> getList(Workbook workbook, int sheetIndex, int headRow) throws Exception {
List> result = new ArrayList>();
Sheet sheet = workbook.getSheetAt(sheetIndex);
ExcelDataDO exceData = new ExcelDataDO(clazz);
List list = getList(sheet, headRow);
exceData.setSheetName(sheet.getSheetName());
exceData.setData(list);
result.add(exceData);
return result;
}
public List getList(Sheet sheet, int headRow) throws Exception {
List list = new ArrayList<>();
int maxCol = 0;
List allFields = getMappedFiled(clazz, null);
Map fieldsMap = new HashMap<>();
for (Field field : allFields) {
if (field.isAnnotationPresent(ExcelField.class)) {
ExcelField attr = field.getAnnotation(ExcelField.class);
int col = getExcelCol(attr.column());
maxCol = Math.max(col, maxCol);
field.setAccessible(true);
fieldsMap.put(col, field);
}
}
int index = 0;
boolean flag = false;
for (Row row : sheet) {
int cellNum = maxCol;
index = index + 1;
if (index <= headRow) {
continue;
}
System.out.println(row.getCell(0));
// System.out.println(row.getCell(0).getStringCellValue());
/*if (row.getCell(0).getStringCellValue().equals("1") || flag) {
flag = true;
} else {
continue;
}*/
/* if (row.getCell(0).getStringCellValue().equals("沈阳市") || flag) {
flag = true;
} else {
continue;
}*/
T entity = null;
for (int j = 0; j <= cellNum; j++) {
Cell cell = row.getCell(j);
if (cell == null) {
continue;
}
if (!v2007) {
cell.setCellType(CellType.STRING);
}
String c = cell.getStringCellValue();
if (c == null || c.equals("")) {
continue;
}
entity = (entity == null ? clazz.newInstance() : entity);
Field field = fieldsMap.get(j);
if (field == null) {
continue;
}
Class> fieldType = field.getType();
if (String.class == fieldType) {
field.set(entity, String.valueOf(c));
} else if ((Integer.TYPE == fieldType)
|| (Integer.class == fieldType)) {
field.set(entity, Integer.parseInt(c));
} else if ((Long.TYPE == fieldType)
|| (Long.class == fieldType)) {
field.set(entity, Long.valueOf(c));
} else if ((Float.TYPE == fieldType)
|| (Float.class == fieldType)) {
field.set(entity, Float.valueOf(c));
} else if ((Short.TYPE == fieldType)
|| (Short.class == fieldType)) {
field.set(entity, Short.valueOf(c));
} else if ((Double.TYPE == fieldType)
|| (Double.class == fieldType)) {
field.set(entity, Double.valueOf(c));
} else if ((BigDecimal.class == fieldType)
|| (BigDecimal.class == fieldType)) {
c = c.replaceAll("\\\\(.*?\\\\)", "");
field.set(entity, new BigDecimal(c));
} else if (Character.TYPE == fieldType) {
if ((c != null) && (c.length() > 0)) {
field.set(entity, Character.valueOf(c.charAt(0)));
}
}
}
if (entity != null) {
list.add(entity);
}
/*if (!flag) {
throw new Exception("未找到有效数据.");
}*/
}
return list;
}
public int getExcelCol(String col) {
col = col.toUpperCase();
int count = -1;
char[] cs = col.toCharArray();
for (int i = 0; i < cs.length; i++) {
count += (cs[i] - 64) * Math.pow(26, cs.length - 1 - i);
}
return count;
}
public int getExcelRow(int row) {
return row -1;
}
public Sheet setHeaders(String sheetName) throws IllegalAccessException, InstantiationException {
Sheet sheet = this.workbook.getSheet(sheetName);
int maxCol = 0;
List allFields = getMappedFiled(clazz, null);
Map> excelMap = new HashMap<>();
for (Field field : allFields) {
if (field.isAnnotationPresent(ExcelHeaderField.class)) {
ExcelHeaderField attr = field.getAnnotation(ExcelHeaderField.class);
int col = getExcelCol(attr.column());
int row = getExcelRow(attr.row());
Map fieldsMap = null;
if (excelMap.containsKey(row)) {
fieldsMap = excelMap.get(row);
} else {
fieldsMap = new HashMap<>();
}
maxCol = Math.max(col, maxCol);
field.setAccessible(true);
fieldsMap.put(col, field);
excelMap.put(row, fieldsMap);
}
}
for (int rowIndex : excelMap.keySet()) {
Row row = sheet.createRow(rowIndex);
Map fieldsMap = excelMap.get(rowIndex);
for (int cellIndex : fieldsMap.keySet()) {
Cell cell = row.createCell(cellIndex);
Field field = fieldsMap.get(cellIndex);
ExcelHeaderField attr = field.getAnnotation(ExcelHeaderField.class);
cell.setCellValue(attr.name());
int rowMerge = StringUtils.isNotEmpty(attr.rowMerge()) ? getExcelCol(attr.rowMerge()) : cellIndex;
int lineMerge = this.lineMerge(rowIndex, cellIndex, excelMap);
if (lineMerge != rowIndex || rowMerge != cellIndex) {
sheet.addMergedRegion(new CellRangeAddress(rowIndex, lineMerge , cellIndex, rowMerge));
}
}
}
return sheet;
}
public void writeData(Sheet sheet, List list, int headRow) throws Exception {
List allAnnoFields = getMappedFiled(clazz, null);
Map fieldsMap = new HashMap<>();
int maxCol = 0;
for (Field field : allAnnoFields) {
if (field.isAnnotationPresent(ExcelField.class)) {
ExcelField attr = field.getAnnotation(ExcelField.class);
int col = getExcelCol(attr.column());
maxCol = Math.max(col, maxCol);
field.setAccessible(true);
fieldsMap.put(col, field);
}
}
int num = 0;
for (ExcelDataBaseDO excelDataBaseDO : list){
Row row = sheet.createRow(num + headRow);
if (excelDataBaseDO != null){
for (int cellIndex : fieldsMap.keySet()) {
Field field = fieldsMap.get(cellIndex);
Object o = field.get(excelDataBaseDO);
row.createCell(cellIndex).setCellValue(String.valueOf(field.get(excelDataBaseDO)));
}
}
num++;
}
System.out.println(headRow);
}
public void writeData(String sheetName,List list) throws Exception {
// HSSFSheet sheet,
Sheet sheet = this.workbook.getSheet(sheetName);
Field[] fields = clazz.getDeclaredFields();
int headRow = 0;
Object object = clazz.newInstance();
for (Field field : fields) {
if ("headRow".equals(field.getName())) {
field.setAccessible(true);
Object o = field.get(object);
headRow = Integer.valueOf(String.valueOf(field.get(object)));
}
}
this.writeData(sheet,list,headRow);
}
// 导出excel 单个sheet页
public HSSFWorkbook exportExcel(HSSFSheet sheet, List list, String name) throws Exception {
// 创建一个Workbook
HSSFWorkbook workbook = new HSSFWorkbook();
// sheet = this.setHeaders(workbook.createSheet(), name);
// writeData(sheet, list);
return workbook;
}
// 创建工作目录
public Workbook createExcel(String... sheetArr) throws Exception {
// 创建一个Workbook
Workbook workbook = new HSSFWorkbook();
for (int i = 0; i < sheetArr.length; i++) {
Sheet sheet = workbook.createSheet(sheetArr[i]);
}
this.workbook = workbook;
return workbook;
}
private List getMappedFiled(Class clazz, List fields) {
if (fields == null) {
fields = new ArrayList<>();
}
Field[] allFields = clazz.getDeclaredFields();
for (Field field : allFields) {
if (field.isAnnotationPresent(ExcelField.class) || field.isAnnotationPresent(ExcelHeaderField.class)) {
fields.add(field);
}
}
if (clazz.getSuperclass() != null && !clazz.getSuperclass().equals(Object.class)) {
getMappedFiled(clazz.getSuperclass(), fields);
}
return fields;
}
private boolean notEmpty(Object object) {
if (object == null || String.valueOf(object).trim().equals("")) {
return false;
}
return true;
}
private int lineMerge(int row, int cell, Map> excelMap){
int lineMerge = row;
boolean flag = true;
for (int rowIndex : excelMap.keySet()) {
if (row < rowIndex) {
Map fieldsMap = excelMap.get(rowIndex);
if (!fieldsMap.containsKey(cell)) {
lineMerge = rowIndex;
} else {
lineMerge = fieldsMap.get(cell).getAnnotation(ExcelHeaderField.class).row() - 1 - 1;
break;
}
}
}
return lineMerge;
}
private boolean match(String regex, String str) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.matches();
}
public static boolean isChartNum(String str) {
String[] array = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
return Arrays.asList(array).contains(str);
}
}
接口测试
// 创建一个workbook
Workbook workbook = excelUtil.createExcel("sheet1");
excelUtil.setHeaders("sheet1");
excelUtil.writeData("sheet1", result);
OutputStream output=response.getOutputStream();
response.reset();
response.setHeader("Access-Control-Expose-Headers", "content-disposition");
response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(excelDataBaseDO.getFileName(), "UTF-8").replace("+","%20"));
response.setContentType("application/octet-stream;charset:utf-8");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Credentials", "true");
workbook.write(output);
output.flush();
output.close();