2022-03-03 13:50:03 +08:00
package com.engine.salary.util.excel ;
import org.apache.commons.lang3.StringUtils ;
import org.apache.commons.lang3.Validate ;
import org.apache.commons.lang3.exception.ContextedRuntimeException ;
import org.apache.poi.ss.usermodel.Sheet ;
import org.springframework.web.multipart.MultipartFile ;
2022-03-07 15:08:56 +08:00
import java.io.InputStream ;
2022-03-03 13:50:03 +08:00
import java.lang.reflect.Field ;
import java.math.BigDecimal ;
2022-03-30 11:29:48 +08:00
import java.util.* ;
import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX ;
2022-03-03 13:50:03 +08:00
/ * *
* Excel 解析工具类
* < p > Copyright : Copyright ( c ) 2022 < / p >
* < p > Company : 泛微软件 < / p >
*
* @author qiantao
* @version 1 . 0
* * /
public class ExcelParseHelper {
//待校验的行号
private static final int PARSE_EXCEL_ROW_VALID_CELL_INDEX = 0 ;
//字符开始下标
private static final int CHARACTER_FIRST_INDEX = 0 ;
/ * *
* 将 Excel 解析为 JavaBean 对象
*
* @param file excel文件
* @param clazz 解析bean的类
* @param sheetIndex excel中第几个sheet , 从0开始
* @param rowIndex 从第几行开始解析 , 第一行是0
* @param standardCellNum 模板验证 , 该sheet应有多少列
* @return
* /
2022-03-31 15:41:55 +08:00
public static < T > List < T > parse2Map ( MultipartFile file , Class < T > clazz , int sheetIndex , int rowIndex , int standardCellNum ) {
List < List < String > > result = parse2Map ( file , sheetIndex , rowIndex , standardCellNum ) ;
2022-03-03 13:50:03 +08:00
List < T > list = new ArrayList < T > ( ) ;
for ( List < String > rowDatas : result ) {
T t = setField ( clazz , rowDatas ) ;
list . add ( t ) ;
}
return list ;
}
2022-03-07 15:08:56 +08:00
/ * *
* 将 Excel 解析为 JavaBean 对象
*
* @param file excel文件
* @param clazz 解析bean的类
* @param sheetIndex excel中第几个sheet , 从0开始
* @param rowIndex 从第几行开始解析 , 第一行是0
* @param standardCellNum 模板验证 , 该sheet应有多少列
* @param fileName 文件名
* @return
* /
2022-03-31 15:41:55 +08:00
public static < T > List < T > parse2Map ( InputStream file , Class < T > clazz , int sheetIndex , int rowIndex , int standardCellNum , String fileName ) {
List < List < String > > result = parse2Map ( file , sheetIndex , rowIndex , standardCellNum , fileName ) ;
2022-03-07 15:08:56 +08:00
List < T > list = new ArrayList < T > ( ) ;
for ( List < String > rowDatas : result ) {
T t = setField ( clazz , rowDatas ) ;
list . add ( t ) ;
}
return list ;
}
2022-03-03 13:50:03 +08:00
/ * *
* < strong > 获取excel数据 。 < / strong >
*
* @param file 文件
* @param sheetIndex 解析第几个sheet
* @param rowIndex 从第几行开始解析 , 第一行为 0 , 依次类推
* @return 二维数据集合
* /
2022-03-31 15:41:55 +08:00
private static List < List < String > > parse2Map ( MultipartFile file , int sheetIndex , int rowIndex , int standardCellNum ) {
2022-03-03 13:50:03 +08:00
Sheet sheet = ExcelSupport . parseFile ( file , sheetIndex ) ;
int rowCount = sheet . getPhysicalNumberOfRows ( ) ; // 总行数
int cellCount = sheet . getRow ( PARSE_EXCEL_ROW_VALID_CELL_INDEX ) . getPhysicalNumberOfCells ( ) ; // 总列数
Validate . isTrue ( standardCellNum = = cellCount , " Error in excel template! Page %s sheet should have %s column data, existing in %s column , please check the template! " , sheetIndex , standardCellNum , cellCount ) ;
2022-03-07 15:08:56 +08:00
List < List < String > > result = new ArrayList < List < String > > ( ) ;
for ( ; rowIndex < rowCount ; rowIndex + + ) {
List < String > cellResult = new ArrayList < String > ( ) ;
for ( int j = 0 ; j < cellCount ; j + + ) {
cellResult . add ( ExcelSupport . getCellValue ( sheet , rowIndex , j ) ) ;
}
result . add ( cellResult ) ;
}
return result ;
}
/ * *
* < strong > 获取excel数据 。 < / strong >
*
* @param file 文件
* @param sheetIndex 解析第几个sheet
* @param rowIndex 从第几行开始解析 , 第一行为 0 , 依次类推
* @return 二维数据集合
* /
2022-03-31 15:41:55 +08:00
private static List < List < String > > parse2Map ( InputStream file , int sheetIndex , int rowIndex , int standardCellNum , String fileName ) {
2022-03-07 15:08:56 +08:00
Sheet sheet = ExcelSupport . parseFile ( file , sheetIndex , fileName ) ;
int rowCount = sheet . getPhysicalNumberOfRows ( ) ; // 总行数
int cellCount = sheet . getRow ( PARSE_EXCEL_ROW_VALID_CELL_INDEX ) . getPhysicalNumberOfCells ( ) ; // 总列数
Validate . isTrue ( standardCellNum = = cellCount , " Error in excel template! Page %s sheet should have %s column data, existing in %s column , please check the template! " , sheetIndex , standardCellNum , cellCount ) ;
2022-03-03 13:50:03 +08:00
List < List < String > > result = new ArrayList < List < String > > ( ) ;
for ( ; rowIndex < rowCount ; rowIndex + + ) {
List < String > cellResult = new ArrayList < String > ( ) ;
for ( int j = 0 ; j < cellCount ; j + + ) {
cellResult . add ( ExcelSupport . getCellValue ( sheet , rowIndex , j ) ) ;
}
result . add ( cellResult ) ;
}
return result ;
}
2022-03-30 11:29:48 +08:00
/ * *
* 将sheet数据转为map
* @param file
* @param sheetIndex sheet下标
* @param rowIndex 从哪行开始解析
* @return
* /
2022-03-31 15:41:55 +08:00
public static List < Map < String , Object > > parse2Map ( InputStream file , int sheetIndex , int rowIndex ) {
2022-03-30 11:29:48 +08:00
Sheet sheet = ExcelSupport . parseFile ( file , sheetIndex , EXCEL_TYPE_XLSX ) ;
int rowCount = sheet . getPhysicalNumberOfRows ( ) ; // 总行数
int cellCount = sheet . getRow ( PARSE_EXCEL_ROW_VALID_CELL_INDEX ) . getPhysicalNumberOfCells ( ) ; // 总列数
List < String > sheetHeader = ExcelSupport . getSheetHeader ( sheet , PARSE_EXCEL_ROW_VALID_CELL_INDEX ) ;
List < Map < String , Object > > result = new ArrayList < > ( ) ;
for ( ; rowIndex < rowCount ; rowIndex + + ) {
Map < String , Object > cellResult = new HashMap < > ( ) ;
for ( int j = 0 ; j < cellCount ; j + + ) {
String key = sheetHeader . get ( j ) ;
cellResult . put ( key , ExcelSupport . getCellValue ( sheet , rowIndex , j ) ) ;
}
result . add ( cellResult ) ;
}
return result ;
}
2022-03-31 15:41:55 +08:00
/ * *
* 将sheet数据转为map
* @param rowIndex 从哪行开始解析
* @return
* /
public static List < Map < String , Object > > parse2Map ( Sheet sheet , int rowIndex ) {
int rowCount = sheet . getPhysicalNumberOfRows ( ) ; // 总行数
int cellCount = sheet . getRow ( PARSE_EXCEL_ROW_VALID_CELL_INDEX ) . getPhysicalNumberOfCells ( ) ; // 总列数
List < String > sheetHeader = ExcelSupport . getSheetHeader ( sheet , PARSE_EXCEL_ROW_VALID_CELL_INDEX ) ;
List < Map < String , Object > > result = new ArrayList < > ( ) ;
for ( ; rowIndex < rowCount ; rowIndex + + ) {
Map < String , Object > cellResult = new HashMap < > ( ) ;
for ( int j = 0 ; j < cellCount ; j + + ) {
String key = sheetHeader . get ( j ) ;
cellResult . put ( key , ExcelSupport . getCellValue ( sheet , rowIndex , j ) ) ;
}
result . add ( cellResult ) ;
}
return result ;
}
/ * *
* 将sheet数据转为List
* @param rowIndex 从哪行开始解析
* @return
* /
public static List < List < String > > parse2List ( Sheet sheet , int rowIndex ) {
int rowCount = sheet . getPhysicalNumberOfRows ( ) ; // 总行数
int cellCount = sheet . getRow ( PARSE_EXCEL_ROW_VALID_CELL_INDEX ) . getPhysicalNumberOfCells ( ) ; // 总列数
List < List < String > > result = new ArrayList < List < String > > ( ) ;
for ( ; rowIndex < rowCount ; rowIndex + + ) {
List < String > cellResult = new ArrayList < String > ( ) ;
for ( int j = 0 ; j < cellCount ; j + + ) {
cellResult . add ( ExcelSupport . getCellValue ( sheet , rowIndex , j ) ) ;
}
result . add ( cellResult ) ;
}
return result ;
}
2022-03-03 13:50:03 +08:00
/ * *
* 为对象的每一个属性赋值
*
* @param clazz
* @param rowDatas
* @param < T >
* @return
* /
private static < T > T setField ( Class < T > clazz , List < String > rowDatas ) {
try {
T obj = clazz . newInstance ( ) ;
Field [ ] fields = clazz . getDeclaredFields ( ) ;
for ( Field field : fields ) {
ExcelProperty excelProperty = field . getAnnotation ( ExcelProperty . class ) ;
if ( excelProperty = = null ) {
continue ;
}
int index = excelProperty . index ( ) ;
Object value = getFieldValue ( field , rowDatas . get ( index ) , excelProperty ) ;
field . setAccessible ( true ) ;
field . set ( obj , value ) ;
}
return obj ;
} catch ( Exception e ) {
throw new ExcelParseException ( e . getMessage ( ) , e ) ;
}
}
/ * *
* < strong > 获取javaBean属性值 < / strong >
*
* @param field javaBean的对象属性
* @param value excel中对应的值
* @param excelProperty javaBean中解析excel注解 , 包含日期格式 、 错误提示信息
* @return
* /
@SuppressWarnings ( " rawtypes " )
private static Object getFieldValue ( Field field , String value , ExcelProperty excelProperty ) {
if ( StringUtils . isEmpty ( value ) ) {
return null ;
}
Object val = null ;
try {
Class typeClass = field . getType ( ) ;
if ( typeClass = = Integer . class ) {
val = Integer . valueOf ( value ) ;
} else if ( typeClass = = Long . class ) {
val = Long . valueOf ( value ) ;
} else if ( typeClass = = Float . class ) {
val = Float . valueOf ( value ) ;
} else if ( typeClass = = Double . class ) {
val = Double . valueOf ( value ) ;
} else if ( typeClass = = Date . class ) {
val = ExcelSupport . getDate ( value , excelProperty . format ( ) ) ;
} else if ( typeClass = = Short . class ) {
val = Short . valueOf ( value ) ;
} else if ( typeClass = = Character . class ) {
val = value . charAt ( CHARACTER_FIRST_INDEX ) ;
} else if ( typeClass = = BigDecimal . class ) {
val = new BigDecimal ( value ) ;
} else {
val = value ;
}
} catch ( Exception e ) {
throw new ContextedRuntimeException ( excelProperty . msg ( ) , e ) ;
}
return val ;
}
}