3、2007及以上版本
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import com.base.infrastructure.log.LoggerManager;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* 2007版本
*/
public class ExcelXlsxReader extends DefaultHandler {
/**
* 单元格中的数据可能的数据类型
*/
enum CellDataType {
BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, DATE, NULL
}
/**
* 共享字符串表
*/
private SharedStringsTable sst;
/**
* 上一次的索引值
*/
private String lastIndex;
/**
* 文件的绝对路径
*/
private String filePath = "";
/**
* 工作表索引
*/
private int sheetIndex = 0;
/**
* sheet名
*/
private String sheetName = "";
/**
* 总行数
*/
private int totalRows = 0;
/**
* 一行内cell集合
*/
private List cellList = new ArrayList();
/**
* 判断整行是否为空行的标记
*/
private boolean flag = false;
/**
* 当前行
*/
private int curRow = 1;
/**
* 前一个列
*/
private int lastCurCol = -1;
/**
* 当前列
*/
private int curCol = 0;
//定义该文档一行最大的单元格数,用来补全一行最后可能缺失的单元格
private int maxcurCol = 0;
// 定义当前读到的列与上一次读到的列中是否有空值(即该单元格什么也没有输入,连空格都不存在)默认为false
private boolean curflag = false;
/**
* T元素标识
*/
private boolean isTElement;
/**
* 异常信息,如果为空则表示没有异常
*/
private String exceptionMessage;
/**
* 单元格数据类型,默认为字符串类型
*/
private CellDataType nextDataType = CellDataType.SSTINDEX;
private final DataFormatter formatter = new DataFormatter();
/**
* 单元格日期格式的索引
*/
private short formatIndex;
/**
* 日期格式字符串
*/
private String formatString;
//定义列名的行索引
private int headerIncex = 1;
//定义数据的行索引
private int dataIndex = 2;
/**
* 单元格
*/
private StylesTable stylesTable;
/**
* 根据文件路径解析
*
* @param path
* @param headerIncex
* @param dataIndex
* @return
* @throws Exception
*/
public int process(String path, int headerIncex, int dataIndex)
throws Exception {
OPCPackage pkg = OPCPackage.open(path);
return init(pkg, headerIncex, dataIndex);
}
/**
* 根据文件流解析(占用内存消耗比文件路径解析大)
*
* @param inputStream
* @param headerIncex
* @param dataIndex
* @return
* @throws Exception
*/
public int process(InputStream inputStream, int headerIncex, int dataIndex)
throws Exception {
OPCPackage pkg = OPCPackage.open(inputStream);
return init(pkg, headerIncex, dataIndex);
}
/**
* 遍历工作簿中所有的电子表格
* 并缓存在mySheetList中
*
* @param pkg
* @param headerIncex
* @param dataIndex
* @return
* @throws Exception
*/
private int init(OPCPackage pkg, int headerIncex, int dataIndex)
throws Exception {
XSSFReader xssfReader = new XSSFReader(pkg);
stylesTable = xssfReader.getStylesTable();
SharedStringsTable sst = xssfReader.getSharedStringsTable();
XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
this.sst = sst;
parser.setContentHandler(this);
XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
while (sheets.hasNext()) { //遍历sheet
curRow = 1; //标记初始行为第一行
if (headerIncex > 0)
this.headerIncex = headerIncex; //设置表头行
if (dataIndex > 0)
this.dataIndex = dataIndex; //设置数据行
sheetIndex++;
InputStream sheet = sheets.next(); //sheets.next()和sheets.getSheetName()不能换位置,否则sheetName报错
sheetName = sheets.getSheetName();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource); //解析excel的每条记录,在这个过程中startElement()、characters()、endElement()这三个函数会依次执行
sheet.close();
}
pkg.close();
return totalRows; //返回该excel文件的总行数,不包括首列和空行
}
/**
* 第一个执行
*
* @param uri
* @param localName
* @param name
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String name, Attributes attributes)
throws SAXException {
//c => 单元格
if ("c".equals(name)) {
//当前单元格的位置
String r = attributes.getValue("r");
int firstDigit = -1;
for (int c = 0; c