POI-Excel解析Excel表单数据
注意
- 接口中public Object parseCell(Cell cell)方法需要自定义实现,这个方法是整个表单解析的核心**
- 针对不同版本Excel创建不同解析器去解析Excel表单有些复杂化了,其实完全可以将AbstractExcelParser.java定义成类似ExcelParser.java的实体类,然后在public Object parseCell(Cell cell)方法中使用instanceof来判断单元格类型,然后决定调用相应的解析方法。这样以来,一个ExcelParser.java实体类就能完成所有功能。
- 如果你对数据解析的格式要求不是很高的话,更简单的办法就是根本不需要在public Object parseCell(Cell cell)方法中使用instanceof判断Cell的类型,直接调用Cell的公共接口方法获取值。
- 此版本不是最终优化版本,写在这里只是为了记录一下笔者写代码的一些思路,供日后回味。
1、Excel表格解析公用接口
package com.dsanjun.poi.parse;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
/**
* Excel表格解析公用接口
*
* @author dyw
* @date 2019年9月11日
*/
public interface ExcelParser {
/**
* 解析所有Sheet
*
* @return 封装成Map的所有Sheet数据的集合,其中键可以为Sheet索引
*/
public Map<Integer, List<Map<String, Object>>> parseSheets();
/**
* 解析指定Sheet
*
* @param sheetIndex sheet索引
* @return List(封装成Map的所有行数据列表)
*/
public List<Map<String, Object>> parseSheet(int sheetIndex);
/**
* 解析Sheet的所有行
*
* @param sheet Sheet对象
* @return List(封装成Map的所有行数据列表)
*/
public List<Map<String, Object>> parseRows(Sheet sheet);
/**
* 解析一行数据
*
* @param row Row对象
* @return Map(单元格对应表头-->单元格的值)
*/
public Map<String, Object> parseRow(Row row);
/**
* 解析单元格数据
*
* @param Cell对象
* @return Object(单元格的值)
*/
public Object parseCell(Cell cell);
}
2、Excel表格解析通用抽象类
package com.dsanjun.poi.parse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import com.dsanjun.poi.bean.TitleCell;
/**
* Excel表格解析通用抽象类,需要根据不同的Excel实现Cell值的获取方法
*
* @author dyw
* @date 2019年9月11日
*/
public abstract class AbstractExcelParser implements ExcelParser {
/** 表头对象列表 */
private List<TitleCell> titleList;
/** 工作簿 */
private Workbook workbook;
/** 标识是否存储sheet列表 */
private Boolean haseSheetList;
/** 工作簿所包含的sheet列表 */
private List<Sheet> sheetList;
/**
* 构造器
*
* @param workbook 工作簿
* @param initSheetList 是否初始化一个Sheet列表集合
*/
public AbstractExcelParser(Workbook workbook, List<TitleCell> titleList, boolean initSheetList) {
this.workbook = workbook;
this.haseSheetList = initSheetList;
this.titleList = titleList;
if (initSheetList) {
initSheetList();
}
}
/**
* 构造器
*
* @param inp 文件输入流
* @param initSheetList 是否初始化一个Sheet列表集合
*/
public AbstractExcelParser(InputStream inp, List<TitleCell> titleList, boolean initSheetList) {
try {
this.workbook = WorkbookFactory.create(inp);
this.haseSheetList = initSheetList;
this.titleList = titleList;
if (initSheetList) {
initSheetList();
}
} catch (EncryptedDocumentException | IOException e) {
e.printStackTrace();
}
}
/**
* 初始化sheet列表
*/
private void initSheetList() {
if (workbook != null) {
sheetList = new ArrayList<Sheet>();
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
sheetList.add(workbook.getSheetAt(i));
}
}
}
@Override
public Map<Integer, List<Map<String, Object>>> parseSheets() {
Map<Integer, List<Map<String, Object>>> sheetDatas = new HashMap<Integer, List<Map<String, Object>>>();
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
List<Map<String, Object>> sheetData = parseSheet(i);
if (sheetData != null) {
sheetDatas.put(i, sheetData);
}
}
return sheetDatas;
}
@Override
public List<Map<String, Object>> parseSheet(int sheetIndex) {
if (haseSheetList) {
return parseRows(sheetList.get(sheetIndex));
} else {
return parseRows(workbook.getSheetAt(sheetIndex));
}
}
@Override
public List<Map<String, Object>> parseRows(Sheet sheet) {
List<Map<String, Object>> rowDatas = new ArrayList<Map<String, Object>>();
if (sheet != null) {
for (int i = sheet.getFirstRowNum() + 1; i < sheet.getLastRowNum(); i++) {
Map<String, Object> rowData = parseRow(sheet.getRow(i));
rowDatas.add(rowData);
}
}
return rowDatas;
}
@Override
public Map<String, Object> parseRow(Row row) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < titleList.size(); i++) {
map.put(titleList.get(i).getName(), parseCell(row.getCell(i)));
}
return map;
}
@Override
public abstract Object parseCell(Cell cell);
public Workbook getWorkbook() {
return workbook;
}
public List<Sheet> getSheetList() {
return sheetList;
}
}
3、03版Excel解析
package com.dsanjun.poi.parse;
import java.io.FileInputStream;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import com.dsanjun.poi.bean.TitleCell;
/**
* 03版Excel解析
*
* @author dyw
* @date 2019年9月11日
*/
public class HSSFExcelParser extends AbstractExcelParser {
public HSSFExcelParser(Workbook workbook, List<TitleCell> titleList, boolean initSheetList) {
super(workbook, titleList, initSheetList);
}
public HSSFExcelParser(FileInputStream fileInputStream, List<TitleCell> titleList, boolean initSheetList) {
super(fileInputStream, titleList, initSheetList);
}
@Override
public Object parseCell(Cell cell) {//这个地方需要自定义实现
return null;
}
}
4、07版Excel解析
package com.dsanjun.poi.parse;
import java.io.InputStream;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import com.dsanjun.poi.bean.TitleCell;
/**
* 07版Excel解析
*
* @author dyw
* @date 2019年9月11日
*/
public class XSSFExcelParser extends AbstractExcelParser {
public XSSFExcelParser(InputStream inp, List<TitleCell> titleList, boolean initSheetList) {
super(inp, titleList, initSheetList);
}
public XSSFExcelParser(Workbook workbook, List<TitleCell> titleList, boolean initSheetList) {
super(workbook, titleList, initSheetList);
}
@Override
public Object parseCell(Cell cell) {//这个地方需要自定义实现
return null;
}
}