1. maven
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
2. 導入的util
/**
* 判斷Excel的版本,獲取Workbook
* @param in
* @param filename
* @return
* @throws IOException
*/
public static Workbook getWorkbok(InputStream in,File file) throws IOException{
Workbook wb = null;
if(file.getName().endsWith(EXCEL_XLS)){ //Excel 2003
wb = new HSSFWorkbook(in);
}else if(file.getName().endsWith(EXCEL_XLSX)){ // Excel 2007/2010
wb = new XSSFWorkbook(in);
}
return wb;
}
public static void main(String[] args) throws Exception {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
try {
// 同時支持Excel 2003、2007
File excelFile = new File("d:/product.xlsx"); // 創建文件對象
FileInputStream in = new FileInputStream(excelFile); // 文件流
checkExcelVaild(excelFile);
Workbook workbook = getWorkbok(in,excelFile);
//Workbook workbook = WorkbookFactory.create(is); // 這種方式 Excel2003/2007/2010都是可以處理的
int sheetCount = workbook.getNumberOfSheets(); // Sheet的數量
/**
* 設置當前excel中sheet的下標:0開始
*/
// Sheet sheet = workbook.getSheetAt(0); // 遍歷第一個Sheet
Sheet sheet = workbook.getSheetAt(2); // 遍歷第三個Sheet
//獲取總行數
// System.out.println(sheet.getLastRowNum());
// 爲跳過第一行目錄設置count
int count = 0;
for (Row row : sheet) {
try {
// 跳過第一和第二行的目錄
if(count < 2 ) {
count++;
continue;
}
//如果當前行沒有數據,跳出循環
if(row.getCell(0).toString().equals("")){
return;
}
//獲取總列數(空格的不計算)
int columnTotalNum = row.getPhysicalNumberOfCells();
System.out.println("總列數:" + columnTotalNum);
System.out.println("最大列數:" + row.getLastCellNum());
//for循環的,不掃描空格的列
// for (Cell cell : row) {
// System.out.println(cell);
// }
int end = row.getLastCellNum();
for (int i = 0; i < end; i++) {
Cell cell = row.getCell(i);
if(cell == null) {
System.out.print("null" + "\t");
continue;
}
Object obj = getValue(cell);
System.out.print(obj + "\t");
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static Object getValue(Cell cell) {
Object obj = null;
switch (cell.getCellTypeEnum()) {
case BOOLEAN:
obj = cell.getBooleanCellValue();
break;
case ERROR:
obj = cell.getErrorCellValue();
break;
case NUMERIC:
obj = cell.getNumericCellValue();
break;
case STRING:
obj = cell.getStringCellValue();
break;
default:
break;
}
return obj;
}
}
3. 合併單元格的excel 處理
https://blog.csdn.net/a919423654/article/details/68946507
List<CellRangeAddress> cras = getCombineCell(sheet);
//isMergedRegion(Sheet sheet,int row ,int column);判斷是不是合併單元格\
int count = sheet.getLastRowNum()+1;//總行數
List<InspectionReport> irs = new ArrayList<>();
for(int i = 1; i < count;i++){
rowIndex = i;
Row row = sheet.getRow(i);
InspectionReport ir = new InspectionReport();
ir.setReportName(getCellValue(row.getCell(0)));
ir.setShift(Double.valueOf(getCellValue(row.getCell(1))).intValue());
ir.setLine(getCellValue(row.getCell(2)));
ir.setStationCode(getCellValue(row.getCell(3)));
ir.setArea(Double.valueOf(getCellValue(row.getCell(4))).intValue());
ir.setReportStatus(Double.valueOf(getCellValue(row.getCell(5))).intValue());
List<InspectionItem> items = new ArrayList<>();
if(isMergedRegion(sheet,i,0)){
int lastRow = getRowNum(cras,sheet.getRow(i).getCell(0),sheet);
for(;i<=lastRow;i++){
row = sheet.getRow(i);
InspectionItem item = new InspectionItem();
item.setItem(getCellValue(row.getCell(6)));
item.setMethod(getCellValue(row.getCell(7)));
item.setMode(getCellValue(row.getCell(8)));
item.setStandardValue(getCellValue(row.getCell(9)));
item.setDeviationValue(getCellValue(row.getCell(10)));
String pinci = getCellValue(row.getCell(11));
Double d = Double.valueOf(pinci);
item.setFrequency(d.intValue());
items.add(item);
}
i--;
}else{
row = sheet.getRow(i);
InspectionItem item = new InspectionItem();
item.setItem(getCellValue(row.getCell(6)));
item.setMethod(getCellValue(row.getCell(7)));
item.setMode(getCellValue(row.getCell(8)));
item.setStandardValue(getCellValue(row.getCell(9)));
item.setDeviationValue(getCellValue(row.getCell(10)));
String pinci = getCellValue(row.getCell(11));
Double d = Double.valueOf(pinci);
item.setFrequency(d.intValue());
items.add(item);
}
ir.setItems(items);
irs.add(ir);
}
public String getCellValue(Cell cell){
if(cell == null) return "";
if(cell.getCellType() == Cell.CELL_TYPE_STRING){
return cell.getStringCellValue();
}else if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){
return String.valueOf(cell.getBooleanCellValue());
}else if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){
return cell.getCellFormula() ;
}else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
return String.valueOf(cell.getNumericCellValue());
}
return "";
}
/**
* 合併單元格處理,獲取合併行
* @param sheet
* @return List<CellRangeAddress>
*/
public List<CellRangeAddress> getCombineCell(Sheet sheet)
{
List<CellRangeAddress> list = new ArrayList<CellRangeAddress>();
//獲得一個 sheet 中合併單元格的數量
int sheetmergerCount = sheet.getNumMergedRegions();
//遍歷所有的合併單元格
for(int i = 0; i<sheetmergerCount;i++)
{
//獲得合併單元格保存進list中
CellRangeAddress ca = sheet.getMergedRegion(i);
list.add(ca);
}
return list;
}
private int getRowNum(List<CellRangeAddress> listCombineCell,Cell cell,Sheet sheet){
int xr = 0;
int firstC = 0;
int lastC = 0;
int firstR = 0;
int lastR = 0;
for(CellRangeAddress ca:listCombineCell)
{
//獲得合併單元格的起始行, 結束行, 起始列, 結束列
firstC = ca.getFirstColumn();
lastC = ca.getLastColumn();
firstR = ca.getFirstRow();
lastR = ca.getLastRow();
if(cell.getRowIndex() >= firstR && cell.getRowIndex() <= lastR)
{
if(cell.getColumnIndex() >= firstC && cell.getColumnIndex() <= lastC)
{
xr = lastR;
}
}
}
return xr;
}
/**
* 判斷單元格是否爲合併單元格,是的話則將單元格的值返回
* @param listCombineCell 存放合併單元格的list
* @param cell 需要判斷的單元格
* @param sheet sheet
* @return
*/
public String isCombineCell(List<CellRangeAddress> listCombineCell,Cell cell,Sheet sheet)
throws Exception{
int firstC = 0;
int lastC = 0;
int firstR = 0;
int lastR = 0;
String cellValue = null;
for(CellRangeAddress ca:listCombineCell)
{
//獲得合併單元格的起始行, 結束行, 起始列, 結束列
firstC = ca.getFirstColumn();
lastC = ca.getLastColumn();
firstR = ca.getFirstRow();
lastR = ca.getLastRow();
if(cell.getRowIndex() >= firstR && cell.getRowIndex() <= lastR)
{
if(cell.getColumnIndex() >= firstC && cell.getColumnIndex() <= lastC)
{
Row fRow = sheet.getRow(firstR);
Cell fCell = fRow.getCell(firstC);
cellValue = getCellValue(fCell);
break;
}
}
else
{
cellValue = "";
}
}
return cellValue;
}
/**
* 獲取合併單元格的值
* @param sheet
* @param row
* @param column
* @return
*/
public String getMergedRegionValue(Sheet sheet ,int row , int column){
int sheetMergeCount = sheet.getNumMergedRegions();
for(int i = 0 ; i < sheetMergeCount ; i++){
CellRangeAddress ca = sheet.getMergedRegion(i);
int firstColumn = ca.getFirstColumn();
int lastColumn = ca.getLastColumn();
int firstRow = ca.getFirstRow();
int lastRow = ca.getLastRow();
if(row >= firstRow && row <= lastRow){
if(column >= firstColumn && column <= lastColumn){
Row fRow = sheet.getRow(firstRow);
Cell fCell = fRow.getCell(firstColumn);
return getCellValue(fCell) ;
}
}
}
return null ;
}
/**
* 判斷指定的單元格是否是合併單元格
* @param sheet
* @param row 行下標
* @param column 列下標
* @return
*/
private boolean isMergedRegion(Sheet sheet,int row ,int column) {
int sheetMergeCount = sheet.getNumMergedRegions();
for (int i = 0; i < sheetMergeCount; i++) {
CellRangeAddress range = sheet.getMergedRegion(i);
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
if(row >= firstRow && row <= lastRow){
if(column >= firstColumn && column <= lastColumn){
return true;
}
}
}
return false;
}
4. 將讀取的數據存入Java對象中 反射方式
https://blog.csdn.net/Revivedsun/article/details/54882870
接着遍歷各個列,由於對象中字段的順序與Excel列順序保持一致,因此使用同樣的列索引即可獲取Excel列單元與對象成員。
private final static Map<Class<?>,TypeHandler> typeHandlerMap = new HashMap<>();
static {
typeHandlerMap.put(Integer.class, new IntegerHandler());
typeHandlerMap.put(Double.class, new DoubleHandler());
typeHandlerMap.put(String.class, new StringHandler());
}
public static <T> List<T> importExcel(File excelFile,Class<T> type) throws InvalidFormatException, IOException, InstantiationException, IllegalAccessException {
XSSFWorkbook workBook = new XSSFWorkbook(excelFile);
List<T> result = new ArrayList<T>();
XSSFSheet sheet = workBook.getSheetAt(0);
for(int ri = sheet.getFirstRowNum() + 1 ; ri <= sheet.getLastRowNum(); ri++) {
Row row = sheet.getRow(ri);
T object = type.newInstance();
Field[] fields = object.getClass().getDeclaredFields();
Field.setAccessible(fields, true);
for(int ci = row.getFirstCellNum(); ci < row.getLastCellNum(); ci++) {
Cell cell = row.getCell(ci);
Object value = getCellValue(cell,fields[ci]);
fields[ci].set(object, value);
}
result.add(object);
Field.setAccessible(fields, false);
}
return result;
}
private static Object getCellValue(Cell cell,Field field)
{
TypeHandler handler = typeHandlerMap.get(field.getType());
if(handler == null) {
return null;
}
return handler.handle(cell, field);
}
public interface TypeHandler {
public Object handle(Cell cell,Field field);
}
public class IntegerHandler implements TypeHandler{
@Override
public Object handle(Cell cell, Field field) {
int type = cell.getCellType();
if(type == Cell.CELL_TYPE_NUMERIC) {
return (int)cell.getNumericCellValue();
}
else if(type == Cell.CELL_TYPE_STRING) {
try {
return Integer.valueOf(cell.getStringCellValue());
}catch(NumberFormatException e) {
return null;
}
}
else {
return null;
}
}
}
public class DoubleHandler implements TypeHandler{
@Override
public Object handle(Cell cell, Field field) {
int type = cell.getCellType();
if(type == Cell.CELL_TYPE_NUMERIC) {
return cell.getNumericCellValue();
}
else if(type == Cell.CELL_TYPE_STRING) {
try {
return Double.valueOf(cell.getNumericCellValue());
}catch(NumberFormatException e) {
return null;
}
}
else {
return null;
}
}
}
public class StringHandler implements TypeHandler{
@Override
public Object handle(Cell cell, Field field) {
int type = cell.getCellType();
if(type != Cell.CELL_TYPE_STRING) {
return "";
}
else {
return cell.getStringCellValue();
}
}
}