1、定義 @ExcelCol 註解
package com.ly.education.elective.api.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* FIELD:用於描述域
* RUNTIME: 在運行時有效(即運行時保留)
* @auther: fly
* @date: 2019/10/5 10:59
* @param:
* @return:
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelCol {
/**
* 列名稱
* @return
*/
String name() default "";
/**
* 列寬度
* @return
*/
int length() default 15;
/**
* 列排序
* @return
*/
int colNum() default 0;
}
2、創建 ExcelUtil 工具類
package com.ly.education.elective.server.utils;
import com.ly.education.elective.api.annotation.ExcelCol;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* @ClassName ExcelUtils
* @Description:
* @Author fly
* @Date 2019/10/5 9:40
*/
@Slf4j
public class ExcelUtils {
/**
* 文件後綴名: .xls
*/
private final static String EXCEL2003 = "xls";
/**
* 文件後綴名: .xlsx
*/
private final static String EXCEL2007 = "xlsx";
/**
*
* 功能描述: 導出 excel
* @auther: fly
* @date: 2019/10/5 11:12
* @param: response HttpServletResponse
* @param: dataList 每個sheet數據源集合
* @param: titleNameList title 標題集合名稱
* @param: sheetNameList sheet 集合名稱
* @param: cls 實體類
* @param: filePath 導出 excel 文件路徑
* @return:
*/
public static <T> void exportExcel(HttpServletResponse response, List<List<T>> dataList, List<String> titleNameList,
List<String> sheetNameList, Class<T> cls, String filePath) {
// 該類屬性數組
Field[] fields = cls.getDeclaredFields();
// 應用了 @ExcelCol 註解的屬性, 且 colNum 大於 0 的屬性集合
List<Field> fieldList = Arrays.stream(fields)
.filter(field -> {
ExcelCol annotation = field.getAnnotation(ExcelCol.class);
// 該屬性有引用該註解, 且列排序號大於 0
if (annotation != null && annotation.colNum() > 0) {
// 當該字段用 private 修飾時 isAccessible() 得到的值是 false, 必須要改成 true 纔可以訪問
field.setAccessible(true);
return true;
}
return false;
}).sorted(Comparator.comparing(field -> {
int col = 0;
ExcelCol annotation = field.getAnnotation(ExcelCol.class);
if (annotation != null) {
col = annotation.colNum();
}
return col;
})).collect(Collectors.toList());
Workbook workbook = new XSSFWorkbook();
if (CollectionUtils.isNotEmpty(dataList)) {
AtomicInteger ak = new AtomicInteger();
// 循環 sheet
dataList.forEach(list -> {
// sheet 名稱
String sheetName = "";
int akIndex = ak.getAndIncrement();
if (sheetNameList != null && akIndex < sheetNameList.size()) {
sheetName = sheetNameList.get(akIndex);
} else {
sheetName = "sheet" + akIndex;
}
Sheet sheet = workbook.createSheet(sheetName);
AtomicInteger ai = new AtomicInteger();
// excel 標題
if (titleNameList != null && akIndex < titleNameList.size()) {
// 創建合併單元格
CellRangeAddress region = new CellRangeAddress(0, 0, 0, fieldList.size() - 1);
// 在 sheet 裏增加合併單元格
sheet.addMergedRegion(region);
Row titleRow = sheet.createRow(ai.getAndIncrement());
Cell cell = titleRow.createCell(0);
CellStyle cellStyle = workbook.createCellStyle();
// 水平居中
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
// 垂直居中
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
Font font = workbook.createFont();
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
font.setFontHeightInPoints((short) 20);
cellStyle.setFont(font);
String titleName = "";
if (titleNameList != null && akIndex < titleNameList.size()) {
titleName = titleNameList.get(akIndex);
} else {
titleName = "標題";
}
cell.setCellStyle(cellStyle);
cell.setCellValue(titleName);
}
// 列標題
{
// 創建新的一行
Row row = sheet.createRow(ai.getAndIncrement());
AtomicInteger aj = new AtomicInteger();
// 寫入標題
fieldList.forEach(field -> {
ExcelCol annotation = field.getAnnotation(ExcelCol.class);
String columnName = "";
if (annotation != null) {
columnName = annotation.name();
sheet.setColumnWidth(annotation.colNum() - 1, annotation.length() * 256);
}
// 創建新的一列
Cell cell = row.createCell(aj.getAndIncrement());
CellStyle cellStyle = workbook.createCellStyle();
// 水平居中
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
// 垂直居中
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
Font font = workbook.createFont();
// 字體
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
cellStyle.setFont(font);
// 列樣式
cell.setCellStyle(cellStyle);
// 列名稱
cell.setCellValue(columnName);
});
}
// 循環數據集合
if (CollectionUtils.isNotEmpty(list)) {
list.forEach(t -> {
// 創建新的一行
Row row1 = sheet.createRow(ai.getAndIncrement());
AtomicInteger aj = new AtomicInteger();
// 循環屬性集合
fieldList.forEach(field -> {
// 屬性類型
Class<?> type = field.getType();
Object value = "";
try {
// 屬性值
value = field.get(t);
} catch (Exception e) {
e.printStackTrace();
}
Cell cell = row1.createCell(aj.getAndIncrement());
CellStyle cellStyle = workbook.createCellStyle();
// 水平居中
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
// 垂直居中
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
cell.setCellStyle(cellStyle);
if (value != null) {
// 如果屬性類型爲 Date
if (type == Date.class) {
cell.setCellValue(value.toString());
} else {
cell.setCellValue(value.toString());
}
}
});
});
}
});
}
String sheet = "";
if (sheetNameList != null && !sheetNameList.isEmpty()) {
sheet = sheetNameList.get(0);
} else {
sheet = "sheet0";
}
// 瀏覽器下載 excel
buildExcelDocument("abbot.xlsx", workbook, response, filePath);
}
/**
*
* 功能描述: 瀏覽器下載 Excel
* @auther: fly
* @date: 2019/10/5 11:40
* @param:
* @return:
*/
private static void buildExcelDocument(String fileName, Workbook workbook, HttpServletResponse response, String filePath) {
try {
FileOutputStream outputStream = new FileOutputStream(filePath);
workbook.write(outputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、在實體類的屬性上標上註解
package com.ly.education.elective.api.vo;
import com.ly.education.elective.api.annotation.ExcelCol;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* @author fly
*
*/
@Getter
@Setter
@ToString
public class CourseSelectionListVo implements Serializable {
/**
* 序列號
*/
private static final long serialVersionUID = -9003609292510835997L;
/**
* 學生學號
*/
@ExcelCol(name = "學號", colNum = 1)
private String studentCode;
/**
* 學生姓名
*/
@ExcelCol(name = "姓名", colNum = 2)
private String studentName;
/**
* 學生行政班級名稱
*/
@ExcelCol(name = "行政班級", colNum = 5)
private String administrativeClassName;
/**
* 專業名稱
*/
@ExcelCol(name = "年級專業", colNum = 4, length = 25)
private String gradeMajorName;
/**
* 學生學院名稱
*/
@ExcelCol(name = "學院", colNum = 3)
private String studentDepartmentName;
}