个人用途,用于将数据解析成json格式使用
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gta.edu.sdk.util.StringUtil;
import org.apache.commons.lang.StringUtils;
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;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author y
* @create 2018-01-18 14:28
* @desc POI读取excel有两种模式,一种是用户模式,一种是事件驱动模式
* 采用SAX事件驱动模式解决XLSX文件,可以有效解决用户模式内存溢出的问题,
* 该模式是POI官方推荐的读取大数据的模式,
* 在用户模式下,数据量较大,Sheet较多,或者是有很多无用的空行的情况下,容易出现内存溢出
* <p>
* 用于解决.xlsx2007版本大数据量问题
**/
public class ExcelXlsxReader extends DefaultHandler {
/**
* 单元格中的数据可能的数据类型
*/
enum CellDataType {
BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, DATE, NULL
}
/**
* 共享字符串表
*/
private SharedStringsTable sst;
/**
* 上一次的内容
*/
private String lastContents;
/**
* 文件的绝对路径
*/
private String filePath = "";
/**
* 工作表索引
*/
private int sheetIndex = 0;
/**
* sheet名
*/
private String sheetName = "";
/**
* 一行内cell集合
*/
private List<String> cellList = new ArrayList<>();
/**
* 单个sheet表的列头集合
*/
private List<String> columnList;
/**
* 单个sheet表的每列的数据类型
*/
private List<String> columnType;
//存储sheet表每行
private JSONObject objSheet;
//单个sheet表的数据
private JSONArray arrSheet = new JSONArray();
//保存所有sheet表的数据
private JSONArray tables = new JSONArray();
//保存所有sheet名称
public List<String> sheetNames = new ArrayList<>();
/**
* 字符串标识
*/
private boolean nextIsString;
/**
* 当前行
*/
private int curRow = 1;
private int curSize;
/**
* 当前列
*/
private int curCol = 0;
private int column = 1;
/**
* T元素标识
*/
private boolean isTElement;
/**
* 异常信息,如果为空则表示没有异常
*/
private String exceptionMessage;
/**
* 单元格数据类型,默认为字符串类型
*/
private CellDataType nextDataType = CellDataType.SSTINDEX;
private final DataFormatter formatter = new DataFormatter();
/**
* 单元格日期格式的索引
*/
private short formatIndex;
/**
* 日期格式字符串
*/
private String formatString;
//定义前一个元素和当前元素的位置,用来计算其中空的单元格数量,如A6和A8等
private String preRef = null, ref = null;
//定义该文档一行最大的单元格数,用来补全一行最后可能缺失的单元格
private String maxRef = null;
/**
* 单元格
*/
private StylesTable stylesTable;
/**
* 有效数据矩形区域,A1:Y2
*/
private String dimension;
/**
* 根据dimension得出每行的数据长度
*/
private int longest;
/**
* 上个有内容的单元格id,判断空单元格
*/
private String lastCellid;
/**
* 上一行id, 判断空行
*/
private String lastRowid;
/**
* 遍历工作簿中所有的电子表格
* 并缓存在mySheetList中
*
* @param file
* @throws Exception
*/
public JSONArray process(File file) throws Exception {
//filePath = filename;
tables.clear();
sheetNames.clear();
//File file=new File(filename);
OPCPackage pkg = OPCPackage.open(file);
XSSFReader xssfReader = new XSSFReader(pkg);
stylesTable = xssfReader.getStylesTable();
SharedStringsTable sst = xssfReader.getSharedStringsTable();
XMLReader parser = this.fetchSheetParser(sst);
//Iterator<InputStream> sheets = xssfReader.getSheetsData();
XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
while (sheets.hasNext()) { //遍历sheet
curRow = 1; //标记初始行为第一行
curSize = 0;
arrSheet.clear();//清除历史数据
if (columnList != null) {
columnList.clear();
}
sheetIndex++;
InputStream sheet = sheets.next(); //sheets.next()和sheets.getSheetName()不能换位置,否则sheetName报错
sheetName = sheets.getSheetName();
sheetNames.add(sheetName);//存储所有sheet名称
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource); //解析excel的每条记录,在这个过程中startElement()、characters()、endElement()这三个函数会依次执行
sheet.close();
objSheet = new JSONObject();
JSONArray json = (JSONArray) arrSheet.clone();
objSheet.put(sheetName, json);
//总数据
tables.add(objSheet);
}
return tables; //返回该excel文件的总行数,不包括首列和空行
}
public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
XML