fix sax read

This commit is contained in:
Looly 2019-09-27 21:12:30 +08:00
parent 4f811fc984
commit 3d8e01fe56
3 changed files with 205 additions and 153 deletions

View File

@ -6,39 +6,57 @@ import cn.hutool.core.util.PageUtil;
/**
* 分页数据结果集
* @author Looly
*
* @param <T> 结果集项的类型
* @author Looly
*/
public class PageResult<T> extends ArrayList<T> {
private static final long serialVersionUID = 9056411043515781783L;
public static final int DEFAULT_PAGE_SIZE = Page.DEFAULT_PAGE_SIZE;
/** 页码 */
/**
* 页码
*/
private int page;
/** 每页结果数 */
/**
* 每页结果数
*/
private int pageSize;
/** 总页数 */
/**
* 总页数
*/
private int totalPage;
/** 总数 */
/**
* 总数
*/
private int total;
//---------------------------------------------------------- Constructor start
/**
* 构造
*/
public PageResult() {
this(0, DEFAULT_PAGE_SIZE);
}
/**
* 构造
*
* @param page 页码
* @param pageSize 每页结果数
*/
public PageResult(int page, int pageSize) {
super(pageSize <= 0 ? DEFAULT_PAGE_SIZE : pageSize);
this.page = page <= 0 ? 0 : page;
this.page = Math.max(page, 0);
this.pageSize = pageSize <= 0 ? DEFAULT_PAGE_SIZE : pageSize;
}
/**
* 构造
*
* @param page 页码
* @param pageSize 每页结果数
* @param total 结果总数
@ -52,14 +70,17 @@ public class PageResult<T> extends ArrayList<T>{
//---------------------------------------------------------- Constructor end
//---------------------------------------------------------- Getters and Setters start
/**
* @return 页码
*/
public int getPage() {
return page;
}
/**
* 设置页码
*
* @param page 页码
*/
public void setPage(int page) {
@ -74,8 +95,10 @@ public class PageResult<T> extends ArrayList<T>{
public int getNumPerPage() {
return pageSize;
}
/**
* 设置每页结果数
*
* @param pageSize 每页结果数
* @deprecated 请使用 {@link #setPageSize(int)}
*/
@ -90,8 +113,10 @@ public class PageResult<T> extends ArrayList<T>{
public int getPageSize() {
return pageSize;
}
/**
* 设置每页结果数
*
* @param pageSize 每页结果数
*/
public void setPageSize(int pageSize) {
@ -104,8 +129,10 @@ public class PageResult<T> extends ArrayList<T>{
public int getTotalPage() {
return totalPage;
}
/**
* 设置总页数
*
* @param totalPage 总页数
*/
public void setTotalPage(int totalPage) {
@ -118,8 +145,10 @@ public class PageResult<T> extends ArrayList<T>{
public int getTotal() {
return total;
}
/**
* 设置总数
*
* @param total 总数
*/
public void setTotal(int total) {

View File

@ -6,6 +6,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import cn.hutool.core.util.ObjectUtil;
import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
@ -39,24 +40,33 @@ import cn.hutool.poi.exceptions.POIException;
* 参考http://www.cnblogs.com/wshsdlau/p/5643862.html
*
* @author looly
*
*/
public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> implements HSSFListener {
/** 如果为公式true表示输出公式计算后的结果值false表示输出公式本身 */
/**
* 如果为公式true表示输出公式计算后的结果值false表示输出公式本身
*/
private boolean isOutputFormulaValues = true;
/** 用于解析公式 */
/**
* 用于解析公式
*/
private SheetRecordCollectingListener workbookBuildingListener;
/** 子工作簿,用于公式计算 */
/**
* 子工作簿用于公式计算
*/
private HSSFWorkbook stubWorkbook;
/** 静态字符串表 */
/**
* 静态字符串表
*/
private SSTRecord sstRecord;
private FormatTrackingHSSFListener formatListener;
/** Sheet边界记录此Record中可以获得Sheet名 */
/**
* Sheet边界记录此Record中可以获得Sheet名
*/
private List<BoundSheetRecord> boundSheetRecords = new ArrayList<>();
private boolean isOutputNextStringRecord;
@ -64,7 +74,9 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
// 存储行记录的容器
private List<Object> rowCellList = new ArrayList<>();
/** 自定义需要处理的sheet编号如果-1表示处理所有sheet */
/**
* 自定义需要处理的sheet编号如果-1表示处理所有sheet
*/
private int rid = -1;
// 当前表索引
private int curRid = -1;
@ -195,6 +207,7 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
}
// ---------------------------------------------------------------------------------------------- Private method start
/**
* 处理单元格值
*
@ -206,52 +219,52 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
switch (record.getSid()) {
case BlankRecord.sid:
// 空白记录
BlankRecord brec = (BlankRecord) record;
rowCellList.add(brec.getColumn(), StrUtil.EMPTY);
rowCellList.add(((BlankRecord) record).getColumn(), StrUtil.EMPTY);
break;
case BoolErrRecord.sid: // 布尔类型
BoolErrRecord berec = (BoolErrRecord) record;
case BoolErrRecord.sid:
// 布尔类型
final BoolErrRecord berec = (BoolErrRecord) record;
rowCellList.add(berec.getColumn(), berec.getBooleanValue());
break;
case FormulaRecord.sid: // 公式类型
FormulaRecord frec = (FormulaRecord) record;
case FormulaRecord.sid:
// 公式类型
FormulaRecord formulaRec = (FormulaRecord) record;
if (isOutputFormulaValues) {
if (Double.isNaN(frec.getValue())) {
if (Double.isNaN(formulaRec.getValue())) {
// Formula result is a string
// This is stored in the next record
isOutputNextStringRecord = true;
} else {
value = formatListener.formatNumberDateCell(frec);
value = formatListener.formatNumberDateCell(formulaRec);
}
} else {
value = '"' + HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression()) + '"';
value = StrUtil.wrap(HSSFFormulaParser.toFormulaString(stubWorkbook, formulaRec.getParsedExpression()), "\"");
}
rowCellList.add(frec.getColumn(), value);
rowCellList.add(formulaRec.getColumn(), value);
break;
case StringRecord.sid:// 单元格中公式的字符串
case StringRecord.sid:
// 单元格中公式的字符串
if (isOutputNextStringRecord) {
// String for formula
StringRecord srec = (StringRecord) record;
value = srec.getString();
// value = ((StringRecord) record).getString();
isOutputNextStringRecord = false;
}
break;
case LabelRecord.sid:
LabelRecord lrec = (LabelRecord) record;
final LabelRecord lrec = (LabelRecord) record;
value = lrec.getValue();
this.rowCellList.add(lrec.getColumn(), value);
break;
case LabelSSTRecord.sid: // 字符串类型
case LabelSSTRecord.sid:
// 字符串类型
LabelSSTRecord lsrec = (LabelSSTRecord) record;
if (sstRecord == null) {
rowCellList.add(lsrec.getColumn(), StrUtil.EMPTY);
} else {
if (null != sstRecord) {
value = sstRecord.getString(lsrec.getSSTIndex()).toString();
rowCellList.add(lsrec.getColumn(), value);
}
rowCellList.add(lsrec.getColumn(), ObjectUtil.defaultIfNull(value, StrUtil.EMPTY));
break;
case NumberRecord.sid: // 数字类型
NumberRecord numrec = (NumberRecord) record;
final NumberRecord numrec = (NumberRecord) record;
final String formatString = formatListener.getFormatString(numrec);
if (formatString.contains(StrUtil.DOT)) {
//浮点数
@ -260,16 +273,15 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
//日期
value = formatListener.formatNumberDateCell(numrec);
} else {
double numValue = numrec.getValue();
final long longPart = (long) numValue;
final double doubleValue = numrec.getValue();
final long longPart = (long) doubleValue;
// 对于无小数部分的数字类型转为Long否则保留原数字
if(longPart == numValue) {
if (((double) longPart) == doubleValue) {
value = longPart;
} else {
value = numValue;
value = doubleValue;
}
}
// 向容器加入列值
rowCellList.add(numrec.getColumn(), value);
break;

View File

@ -34,21 +34,30 @@ import cn.hutool.poi.exceptions.POIException;
*
* @author Looly
* @since 3.1.2
*
*/
public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> implements ContentHandler {
// saxParser
private static final String CLASS_SAXPARSER = "org.apache.xerces.parsers.SAXParser";
/** Cell单元格元素 */
/**
* Cell单元格元素
*/
private static final String C_ELEMENT = "c";
/** 行元素 */
/**
* 行元素
*/
private static final String ROW_ELEMENT = "row";
/** Cell中的行列号 */
/**
* Cell中的行列号
*/
private static final String R_ATTR = "r";
/** Cell类型 */
/**
* Cell类型
*/
private static final String T_ELEMENT = "t";
/** SSTSharedStringsTable 的索引 */
/**
* SSTSharedStringsTable 的索引
*/
private static final String S_ATTR_VALUE = "s";
// 列中属性值
private static final String T_ATTR_VALUE = "t";
@ -73,9 +82,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
private String maxCellCoordinate;
// 单元格的格式表对应style.xml
private StylesTable stylesTable;
// 单元格存储格式的索引对应style.xml中的numFmts元素的子元素索引
private int numFmtIndex;
// 单元格存储的格式化字符串nmtFmt的formateCode属性的值
// 单元格存储的格式化字符串nmtFmt的formatCode属性的值
private String numFmtString;
// sheet的索引
private int sheetIndex;
@ -83,7 +90,9 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
// 存储每行的列元素
List<Object> rowCellList = new ArrayList<>();
/** 行处理器 */
/**
* 行处理器
*/
private RowHandler rowHandler;
/**
@ -178,7 +187,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
* 读到一个xml开始标签时的回调处理方法
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
public void startElement(String uri, String localName, String qName, Attributes attributes) {
// 单元格元素
if (C_ELEMENT.equals(qName)) {
@ -203,11 +212,12 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
/**
* 设置单元格的类型
*
* @param attribute
* @param attribute 属性
*/
private void setCellType(Attributes attribute) {
// 重置numFmtIndex,numFmtString的值
numFmtIndex = 0;
// 单元格存储格式的索引对应style.xml中的numFmts元素的子元素索引
int numFmtIndex;
// numFmtString的值
numFmtString = "";
this.cellDataType = CellDataType.of(attribute.getValue(T_ATTR_VALUE));
@ -232,13 +242,14 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
* 标签结束的回调处理方法
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
public void endElement(String uri, String localName, String qName) {
final String contentStr = StrUtil.trim(lastContent);
if (T_ELEMENT.equals(qName)) {
// type标签
// rowCellList.add(curCell++, contentStr);
} else if (C_ELEMENT.equals(qName)) {
// if (T_ELEMENT.equals(qName)) {
// // type标签
// // rowCellList.add(curCell++, contentStr);
// } else
if (C_ELEMENT.equals(qName)) {
// cell标签
Object value = ExcelSaxUtil.getDataValue(this.cellDataType, contentStr, this.sharedStringsTable, this.numFmtString);
// 补全单元格之间的空格
@ -259,8 +270,8 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
rowHandler.handle(sheetIndex, curRow, rowCellList);
// 一行结束
// 清空rowCellList,
rowCellList.clear();
// 新建一个新列之前的列抛弃可能被回收或rowHandler处理
rowCellList = new ArrayList<>(curCell + 1);
// 行数增加
curRow++;
// 当前列置0
@ -275,7 +286,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
* s标签结束的回调处理方法
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
public void characters(char[] ch, int start, int length) {
// 得到单元格内容的值
lastContent = lastContent.concat(new String(ch, start, length));
}
@ -290,42 +301,43 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
* ?xml标签的回调处理方法
*/
@Override
public void startDocument() throws SAXException {
public void startDocument() {
// pass
}
@Override
public void endDocument() throws SAXException {
public void endDocument() {
// pass
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
public void startPrefixMapping(String prefix, String uri) {
// pass
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
public void endPrefixMapping(String prefix) {
// pass
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
public void ignorableWhitespace(char[] ch, int start, int length) {
// pass
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
public void processingInstruction(String target, String data) {
// pass
}
@Override
public void skippedEntity(String name) throws SAXException {
public void skippedEntity(String name) {
// pass
}
// --------------------------------------------------------------------------------------- Pass method end
// --------------------------------------------------------------------------------------- Private method start
/**
* 处理流中的Excel数据
*
@ -359,12 +371,11 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
/**
* 获取sheet的解析器
*
* @param sharedStringsTable
* @return {@link XMLReader}
* @throws SAXException SAX异常
*/
private XMLReader fetchSheetReader() throws SAXException {
XMLReader xmlReader = null;
XMLReader xmlReader;
try {
xmlReader = XMLReaderFactory.createXMLReader(CLASS_SAXPARSER);
} catch (SAXException e) {