java自定義Excel導出工具
一、引入
預備知識:
- java的自定義注解
- java反射
- poi的常用api
注解和反射學習:
自定義和反射的内容比較多就不行細緻闡述了,不了解的可以點選下方進行跳轉
自定義注解
java反射
poi的maven引入:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
poi的常用api:
1.建立一個工作簿
Workbook wb = new XSSFWorkbook();
...
try (OutputStream fileOut = new FileOutputStream("workbook.xlsx")) {
wb.write(fileOut);
}
2.建立一個工作表
Sheet sheet1 = wb.createSheet("new sheet");
Sheet sheet2 = wb.createSheet("second sheet");
3.建立一個單元格
Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow(0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);
二、定義導出工具
自定義Excel注解:
目的:通過反射擷取對象中帶有
Excel
注解的字段,并進行解析導出
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excel {
/**
* 導出到Excel中的名字.
*/
String name() default "";
/**
* 日期格式, 如: yyyy-MM-dd
*/
String dateFormat() default "";
}
自定義ExcelUtil工具類:
目的:通過反射和Excel注解
/**
* Excel的工具類
*/
public class ExcelUtils<T> {
/**
* 工作簿
*/
private Workbook wb;
/**
* 工作表
*/
private Sheet sheet;
/**
* class對象
*/
private Class<T> clazz;
/**
* 導出導入資料
*/
private List<T> list;
/**
* 含有Excel注解的字段
*/
private List<Field> fields;
private ExcelUtils(){
}
public ExcelUtils(Class<T> clazz){
this.clazz = clazz;
}
/**
* 資料導出excel
*
* @param list 目标資料
* @param sheetName 工作表名稱
*/
public void exportExcel(List<T> list, String sheetName) {
// 初始化
init(list, sheetName);
// sheet第一行加入名稱資料
createTopRow();
// sheet其他行,添加目标資料
try {
createOtherRow(list);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
try(OutputStream outFile = new FileOutputStream("D:3.xlsx")){
wb.write(outFile);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
wb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 添加導出資料
*/
private void createOtherRow(List<T> list) throws IllegalAccessException {
for(int rowNum = 1; rowNum <= list.size(); rowNum++) {
Row row = sheet.createRow(rowNum);
T t = list.get(rowNum - 1);
for(int colNum = 0; colNum < fields.size(); colNum++) {
Cell cell = row.createCell(colNum);
Field field = fields.get(colNum);
field.setAccessible(true);
// 單元格設定值
addCell(cell, field, t);
}
}
}
/**
* 單元格中添加資料
*
* @param cell 單元格
* @param field 字段
* @param t list中的一條資料
*/
private void addCell(Cell cell, Field field, T t) throws IllegalAccessException {
Class<?> fieldType = field.getType();
if (String.class == fieldType)
{
cell.setCellValue((String) field.get(t));
}
else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
{
cell.setCellValue((Integer) field.get(t));
}
else if ((Long.TYPE == fieldType) || (Long.class == fieldType))
{
cell.setCellValue((Long) field.get(t));
}
else if ((Double.TYPE == fieldType) || (Double.class == fieldType))
{
cell.setCellValue((Double) field.get(t));
}
else if ((Float.TYPE == fieldType) || (Float.class == fieldType))
{
cell.setCellValue((Float) field.get(t));
}
else if (Date.class == fieldType)
{
String dateFormat = field.getAnnotation(Excel.class).dateFormat();
cell.setCellValue(dateFormat((Date) field.get(t), dateFormat));
}
}
/**
* 時間格式轉換
* @param date 日期
* @param dateFormat 日期格式
* @return
*/
private String dateFormat(Date date, String dateFormat) {
if (dateFormat == null || "".equals(dateFormat)) {
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
SimpleDateFormat df = new SimpleDateFormat(dateFormat);
return df.format(date);
}
/**
* sheet第一行加入名稱資料
*/
private void createTopRow() {
Row row = sheet.createRow(0);
for(int index = 0; index < fields.size(); index++){
Cell cell = row.createCell(index);
cell.setCellValue(fields.get(index).getAnnotation(Excel.class).name());
}
}
/**
* 資料導出excel
*
* @param data 目标資料
*/
public void exportExcel(List<T> data){
this.exportExcel(data, "sheet");
}
/**
* 初始化
* 1.建立一個工作簿(Workbook)
* 2.根據一個sheetName, 建立一個工作表(sheet)
* 3.通過反射,擷取包含Excel注解的字段
*
* @param data 目标資料
* @param sheetName 工作表名稱
*/
public void init(List<T> data, String sheetName){
if(data == null) {
this.list = new ArrayList<>();
}
// 建立工作簿
createWorkbook();
// 建立工作表
createSheet(sheetName);
// 初始化Fields
filterFields();
}
/**
* 建立工作簿
*
* @param sheetName sheet的名稱
*/
private void createSheet(String sheetName) {
this.sheet = wb.createSheet(sheetName);
}
/**
* 建立工作簿
*/
private void createWorkbook() {
this.wb = new SXSSFWorkbook();
}
/**
* 過濾出帶有Excel注解的字段
*/
private void filterFields(){
this.fields = Arrays.
asList(clazz.getDeclaredFields()).
stream().
filter(item -> item.isAnnotationPresent(Excel.class))
.collect(Collectors.toList());
}
}
導出測試:
第一步準備要導出的對象(這邊引用了
lombok
)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
@Excel(name = "姓名")
private String name;
@Excel(name = "年齡")
private Integer age;
@Excel(name = "出生日期", dateFormat = "yyyy-MM-dd")
private Date birthday;
}
導出測試:
public class Demo1 {
public static void main(String[] args) throws IOException {
// 準備資料
ArrayList<Student> data = new ArrayList<>();
Student student = new Student();
student.setName("tom");
student.setAge(19);
student.setBirthday(new Date());
data.add(student);
// 導出Excel
ExcelUtils<Student> utils = new ExcelUtils<>(Student.class);
utils.exportExcel(data);
}
}
運作結果: