直接上代码:
package com.limai.baseknowledge.poi;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.formula.WorkbookDependentFormula;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @Author: bingley
* @Date: 2019/3/1 9:57
* @Desc:
*/
@Slf4j
public class PoiUtils {
private static final String XLS = "xls";
private static final String XLSX = "xlsx";
private static final List<String> numericalTypeList = Arrays.asList("int", "float", "long");
/**
* 数据导出Excel
*
* @param sheetName
* @param dataList
* @param titles
* @param columnNames
* @return :
*/
public static HSSFWorkbook exportExcel(String sheetName, List<?> dataList, List<String> titles, List<String> columnNames) {
if (CollectionUtils.isEmpty(dataList) || CollectionUtils.isEmpty(titles)
|| CollectionUtils.isEmpty(columnNames) || titles.size() != columnNames.size()) {
throw new IllegalArgumentException("Excel导入参数不合法!");
}
HSSFWorkbook wb = new HSSFWorkbook();
if (StringUtils.isEmpty(sheetName)) {
sheetName = "sheet";
}
HSSFSheet sheet = wb.createSheet(sheetName);
int dataSize = dataList.size();
int titleSize = titles.size();
int columnSize = columnNames.size();
HSSFRow titleRow = sheet.createRow(0);
// 设置固定样式
for (int columnIndex = 0; columnIndex < titleSize; columnIndex++) {
sheet.setColumnWidth(columnIndex, 6000);
}
HSSFCellStyle style = wb.createCellStyle();
try {
// 写入标题栏
for (int columnIndex = 0; columnIndex < titleSize; columnIndex++) {
HSSFCell rowCell = titleRow.createCell(columnIndex);
rowCell.setCellValue(titles.get(columnIndex));
rowCell.setCellStyle(style);
}
// 写入数据
for (int rowIndex = 1; rowIndex < dataSize + 1; rowIndex++) {
Object obj = dataList.get(rowIndex - 1);
Class clazz = obj.getClass();
HSSFRow dataRow = sheet.createRow(rowIndex);
for (int columnIndex = 0; columnIndex < columnSize; columnIndex++) {
String column = columnNames.get(columnIndex);
String UColumn = Character.toUpperCase(column.charAt(0)) + column.substring(1, column.length());
String getMethodName = "get" + UColumn;
Method method = clazz.getDeclaredMethod(getMethodName);
//返回类型
String returnType = method.getReturnType().getName();
Object invoke = method.invoke(obj);
String data = invoke == null ? "" : method.invoke(obj).toString();
HSSFCell dataCell = dataRow.createCell(columnIndex);
switch (returnType) {
case "int":
dataCell.setCellValue(Integer.parseInt(data));
break;
case "long":
dataCell.setCellValue(Long.parseLong(data));
break;
case "float":
dataCell.setCellValue(Float.parseFloat(data));
break;
case "double":
dataCell.setCellValue(Double.parseDouble(data));
break;
default:
dataCell.setCellValue(data);
}
}
}
} catch (Exception e) {
log.error("POIUtils Excel 导出异常{}", e);
return null;
}
return wb;
}
/**
* 数据导出Excel
* 使用要求:数据对象的属性个数顺序要与excel的每一列对应
*
* @param filePath
* @param tClass
* @return :
*/
public static <T> List<T> readExcel(String filePath, Class<T> tClass) {
try {
File file = new File(filePath);
//检查文件
checkFile(file);
// 根据excel版本获取workbook
Workbook wb = getWorkBook(file);
List<T> dataList = new ArrayList<>();
// 暂只考虑只有一个sheet的情况
Sheet sheet = wb.getSheetAt(0);
Row rowTitle = sheet.getRow(0);
int firstRowNum = sheet.getFirstRowNum();
int lastRowNum = sheet.getLastRowNum();
short firstCellNum = rowTitle.getFirstCellNum();
short lastCellNum = rowTitle.getLastCellNum();
//获取所有属性
Field[] fields = tClass.getDeclaredFields();
// 读取每一行数据
for (int rowIndex = firstRowNum + 1; rowIndex < lastRowNum; rowIndex++) {
//每一行创建一个对象
T obj = tClass.newInstance();
Row row = sheet.getRow(rowIndex);
//读取每一列的属性
for(int cellIndex=firstCellNum;cellIndex<lastCellNum;cellIndex++){
Cell cell = row.getCell(cellIndex);
//拿到每个cell的值
String cellValue = getCellValueAsString(cell);
Field field = fields[cellIndex];
String fieldName = field.getName();
// 通过反射拿到每个属性的setter方法
Class<?> fieldType = field.getType();
String UField="set"+Character.toUpperCase(fieldName.charAt(0))+fieldName.substring(1,fieldName.length());
Method method = tClass.getDeclaredMethod(UField, fieldType);
String fieldTypeName = fieldType.getName();
Object fieldValue;
// 当数字类型的值为空时,填“0”,以免转换异常
if(StringUtils.isEmpty(cellValue)&&numericalTypeList.contains(fieldTypeName)){
cellValue="0";
}
// 根据属性类型转换属性值
switch (fieldTypeName){
case "int":
fieldValue=Integer.parseInt(cellValue) ;
break;
case "float":
fieldValue=Float.parseFloat(cellValue);
break;
case "long":
fieldValue=Long.parseLong(cellValue);
break;
default:
fieldValue=cellValue;
}
// 执行setter方法
method.invoke(obj,fieldValue);
}
//添加到list
dataList.add(obj);
}
return dataList;
} catch (Exception e) {
log.error("Excel导入异常{}",e);
return null;
}
}
private static void checkFile(File file) throws Exception {
if (null == file) {
throw new NoSuchFieldException("未找到文件!");
}
String fileName = file.getName();
if (!fileName.endsWith(XLS) && (!fileName.endsWith(XLSX))) {
throw new IllegalArgumentException(fileName + "不是Excel文件");
}
}
private static Workbook getWorkBook(File file) throws Exception {
Workbook wb = null;
InputStream is = null;
String fileName = file.getName();
is = new FileInputStream(file);
if (fileName.endsWith(XLS)) { //Excel 2003
wb = new HSSFWorkbook(is);
} else if (fileName.endsWith(XLSX)) { // Excel 2007
wb = new XSSFWorkbook(is);
}
return wb;
}
private static String getCellValueAsString(Cell cell){
// 将数字类型先转换为String类型,避免出现1读成1.0情况
if(CellType.NUMERIC.equals(cell.getCellType())){
cell.setCellType(CellType.STRING);
}
CellType cellType = cell.getCellType();
switch (cellType){
case STRING:
return cell.getStringCellValue();
case FORMULA:
return cell.getCellFormula();
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case ERROR:
return "非法字符";
default:
return "未知类型";
}
}
}