mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add default method
This commit is contained in:
parent
44fe8904a2
commit
6b6366e1ef
@ -22,10 +22,13 @@
|
|||||||
* 【core 】 ImgUtil增加去除背景色的方法(pr#124@Gitee)
|
* 【core 】 ImgUtil增加去除背景色的方法(pr#124@Gitee)
|
||||||
* 【system 】 OshiUtil增加获取CPU使用率的方法(pr#124@Gitee)
|
* 【system 】 OshiUtil增加获取CPU使用率的方法(pr#124@Gitee)
|
||||||
* 【crypto 】 AsymmetricAlgorithm去除EC(issue#887@Github)
|
* 【crypto 】 AsymmetricAlgorithm去除EC(issue#887@Github)
|
||||||
|
* 【cache 】 超时缓存使用的线程池大小默认为1(issue#890@Github)
|
||||||
|
* 【poi 】 ExcelSaxReader支持handleCell方法
|
||||||
|
|
||||||
### Bug修复
|
### Bug修复
|
||||||
* 【core 】 修复SimpleCache死锁问题(issue#I1HOKB@Gitee)
|
* 【core 】 修复SimpleCache死锁问题(issue#I1HOKB@Gitee)
|
||||||
* 【core 】 修复SemaphoreRunnable释放问题(issue#I1HLQQ@Gitee)
|
* 【core 】 修复SemaphoreRunnable释放问题(issue#I1HLQQ@Gitee)
|
||||||
|
* 【poi 】 修复Sax方式读取Excel行号错误问题(issue#882@Gitee)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ public enum GlobalPruneTimer {
|
|||||||
if (null != pruneTimer) {
|
if (null != pruneTimer) {
|
||||||
shutdownNow();
|
shutdownNow();
|
||||||
}
|
}
|
||||||
this.pruneTimer = new ScheduledThreadPoolExecutor(16, r -> ThreadUtil.newThread(r, StrUtil.format("Pure-Timer-{}", cacheTaskNumber.getAndIncrement())));
|
this.pruneTimer = new ScheduledThreadPoolExecutor(1, r -> ThreadUtil.newThread(r, StrUtil.format("Pure-Timer-{}", cacheTaskNumber.getAndIncrement())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -554,7 +554,7 @@ public class Img implements Serializable {
|
|||||||
* @return 处理过的图片
|
* @return 处理过的图片
|
||||||
*/
|
*/
|
||||||
public Image getImg() {
|
public Image getImg() {
|
||||||
return this.targetImage;
|
return null == this.targetImage ? this.srcImage : this.targetImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +21,13 @@ public class ImgTest {
|
|||||||
Img.from(FileUtil.file("f:/test/4347273249269e3fb272341acc42d4e.jpg")).setQuality(0.8).write(FileUtil.file("f:/test/test_dest.jpg"));
|
Img.from(FileUtil.file("f:/test/4347273249269e3fb272341acc42d4e.jpg")).setQuality(0.8).write(FileUtil.file("f:/test/test_dest.jpg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void writeTest() {
|
||||||
|
final Img from = Img.from(FileUtil.file("d:/test/81898311-001d6100-95eb-11ea-83c2-a14d7b1010bd.png"));
|
||||||
|
ImgUtil.write(from.getImg(), FileUtil.file("d:/test/dest.jpg"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void roundTest() {
|
public void roundTest() {
|
||||||
|
@ -102,7 +102,8 @@ public class ImgUtilTest {
|
|||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void compressTest() {
|
public void compressTest() {
|
||||||
ImgUtil.compress(FileUtil.file("e:/pic/1111.png"), FileUtil.file("e:/pic/1111_target.jpg"), 0.8f);
|
ImgUtil.compress(FileUtil.file("d:/test/dest.png"),
|
||||||
|
FileUtil.file("d:/test/1111_target.jpg"), 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package cn.hutool.poi.excel.sax;
|
||||||
|
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel的XML中属性名枚举
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 5.3.6
|
||||||
|
*/
|
||||||
|
public enum AttributeName {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行列号属性,行标签下此为行号属性名,cell标签下下为列号属性名
|
||||||
|
*/
|
||||||
|
r,
|
||||||
|
/**
|
||||||
|
* ST(StylesTable) 的索引,样式index,用于获取行或单元格样式
|
||||||
|
*/
|
||||||
|
s,
|
||||||
|
/**
|
||||||
|
* Type类型,单元格类型属性,见{@link CellDataType}
|
||||||
|
*/
|
||||||
|
t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否匹配给定属性
|
||||||
|
*
|
||||||
|
* @param attributeName 属性
|
||||||
|
* @return 是否匹配
|
||||||
|
*/
|
||||||
|
public boolean match(String attributeName) {
|
||||||
|
return this.name().equals(attributeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从属性里列表中获取对应属性值
|
||||||
|
*
|
||||||
|
* @param attributes 属性列表
|
||||||
|
* @return 属性值
|
||||||
|
*/
|
||||||
|
public String getValue(Attributes attributes){
|
||||||
|
return attributes.getValue(name());
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ public enum CellDataType {
|
|||||||
FORMULA("str"),
|
FORMULA("str"),
|
||||||
/** 富文本类型 */
|
/** 富文本类型 */
|
||||||
INLINESTR("inlineStr"),
|
INLINESTR("inlineStr"),
|
||||||
/** 字符串类型 */
|
/** 共享字符串索引类型 */
|
||||||
SSTINDEX("s"),
|
SSTINDEX("s"),
|
||||||
/** 数字类型 */
|
/** 数字类型 */
|
||||||
NUMBER(""),
|
NUMBER(""),
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package cn.hutool.poi.excel.sax;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签名枚举
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 5.3.6
|
||||||
|
*/
|
||||||
|
public enum ElementName {
|
||||||
|
/**
|
||||||
|
* 行标签名,表示一行
|
||||||
|
*/
|
||||||
|
row,
|
||||||
|
/**
|
||||||
|
* 单元格标签名,表示一个单元格
|
||||||
|
*/
|
||||||
|
c;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给定标签名是否匹配当前标签
|
||||||
|
*
|
||||||
|
* @param elementName 标签名
|
||||||
|
* @return 是否匹配
|
||||||
|
*/
|
||||||
|
public boolean match(String elementName){
|
||||||
|
return this.name().equals(elementName);
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ import org.apache.poi.hssf.record.BOFRecord;
|
|||||||
import org.apache.poi.hssf.record.BlankRecord;
|
import org.apache.poi.hssf.record.BlankRecord;
|
||||||
import org.apache.poi.hssf.record.BoolErrRecord;
|
import org.apache.poi.hssf.record.BoolErrRecord;
|
||||||
import org.apache.poi.hssf.record.BoundSheetRecord;
|
import org.apache.poi.hssf.record.BoundSheetRecord;
|
||||||
|
import org.apache.poi.hssf.record.CellValueRecordInterface;
|
||||||
import org.apache.poi.hssf.record.FormulaRecord;
|
import org.apache.poi.hssf.record.FormulaRecord;
|
||||||
import org.apache.poi.hssf.record.LabelRecord;
|
import org.apache.poi.hssf.record.LabelRecord;
|
||||||
import org.apache.poi.hssf.record.LabelSSTRecord;
|
import org.apache.poi.hssf.record.LabelSSTRecord;
|
||||||
@ -77,7 +78,7 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
* 自定义需要处理的sheet编号,如果-1表示处理所有sheet
|
* 自定义需要处理的sheet编号,如果-1表示处理所有sheet
|
||||||
*/
|
*/
|
||||||
private int rid = -1;
|
private int rid = -1;
|
||||||
// 当前表索引
|
// 当前rid索引
|
||||||
private int curRid = -1;
|
private int curRid = -1;
|
||||||
|
|
||||||
private final RowHandler rowHandler;
|
private final RowHandler rowHandler;
|
||||||
@ -193,7 +194,7 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
if (record instanceof MissingCellDummyRecord) {
|
if (record instanceof MissingCellDummyRecord) {
|
||||||
// 空值的操作
|
// 空值的操作
|
||||||
MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
|
MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
|
||||||
addToRowCellList(mc.getColumn(), StrUtil.EMPTY);
|
addToRowCellList(mc);
|
||||||
} else if (record instanceof LastCellOfRowDummyRecord) {
|
} else if (record instanceof LastCellOfRowDummyRecord) {
|
||||||
// 行结束
|
// 行结束
|
||||||
processLastCell((LastCellOfRowDummyRecord) record);
|
processLastCell((LastCellOfRowDummyRecord) record);
|
||||||
@ -208,17 +209,40 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
// ---------------------------------------------------------------------------------------------- Private method start
|
// ---------------------------------------------------------------------------------------------- Private method start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将单元格数据加入到行列表中
|
* 将空数据加入到行列表中
|
||||||
* @param index 加入位置
|
*
|
||||||
* @param value 值
|
* @param record MissingCellDummyRecord
|
||||||
*/
|
*/
|
||||||
private void addToRowCellList(int index, Object value){
|
private void addToRowCellList(MissingCellDummyRecord record) {
|
||||||
while(index > this.rowCellList.size()){
|
addToRowCellList(record.getRow(), record.getColumn(), StrUtil.EMPTY);
|
||||||
// 对于中间无数据的单元格补齐空白
|
|
||||||
this.rowCellList.add(StrUtil.EMPTY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rowCellList.add(index, value);
|
/**
|
||||||
|
* 将单元格数据加入到行列表中
|
||||||
|
*
|
||||||
|
* @param record 单元格
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
private void addToRowCellList(CellValueRecordInterface record, Object value) {
|
||||||
|
addToRowCellList(record.getRow(), record.getColumn(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将单元格数据加入到行列表中
|
||||||
|
*
|
||||||
|
* @param row 行号
|
||||||
|
* @param column 单元格
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
private void addToRowCellList(int row, int column, Object value) {
|
||||||
|
while (column > this.rowCellList.size()) {
|
||||||
|
// 对于中间无数据的单元格补齐空白
|
||||||
|
this.rowCellList.add(StrUtil.EMPTY);
|
||||||
|
this.rowHandler.handleCell(this.curRid, row, rowCellList.size() - 1, value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rowCellList.add(column, value);
|
||||||
|
this.rowHandler.handleCell(this.curRid, row, column, value, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,12 +256,12 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
switch (record.getSid()) {
|
switch (record.getSid()) {
|
||||||
case BlankRecord.sid:
|
case BlankRecord.sid:
|
||||||
// 空白记录
|
// 空白记录
|
||||||
addToRowCellList(((BlankRecord) record).getColumn(), StrUtil.EMPTY);
|
addToRowCellList(((BlankRecord) record), StrUtil.EMPTY);
|
||||||
break;
|
break;
|
||||||
case BoolErrRecord.sid:
|
case BoolErrRecord.sid:
|
||||||
// 布尔类型
|
// 布尔类型
|
||||||
final BoolErrRecord berec = (BoolErrRecord) record;
|
final BoolErrRecord berec = (BoolErrRecord) record;
|
||||||
addToRowCellList(berec.getColumn(), berec.getBooleanValue());
|
addToRowCellList(berec, berec.getBooleanValue());
|
||||||
break;
|
break;
|
||||||
case FormulaRecord.sid:
|
case FormulaRecord.sid:
|
||||||
// 公式类型
|
// 公式类型
|
||||||
@ -253,7 +277,7 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
} else {
|
} else {
|
||||||
value = StrUtil.wrap(HSSFFormulaParser.toFormulaString(stubWorkbook, formulaRec.getParsedExpression()), "\"");
|
value = StrUtil.wrap(HSSFFormulaParser.toFormulaString(stubWorkbook, formulaRec.getParsedExpression()), "\"");
|
||||||
}
|
}
|
||||||
addToRowCellList(formulaRec.getColumn(), value);
|
addToRowCellList(formulaRec, value);
|
||||||
break;
|
break;
|
||||||
case StringRecord.sid:
|
case StringRecord.sid:
|
||||||
// 单元格中公式的字符串
|
// 单元格中公式的字符串
|
||||||
@ -266,7 +290,7 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
case LabelRecord.sid:
|
case LabelRecord.sid:
|
||||||
final LabelRecord lrec = (LabelRecord) record;
|
final LabelRecord lrec = (LabelRecord) record;
|
||||||
value = lrec.getValue();
|
value = lrec.getValue();
|
||||||
addToRowCellList(lrec.getColumn(), value);
|
addToRowCellList(lrec, value);
|
||||||
break;
|
break;
|
||||||
case LabelSSTRecord.sid:
|
case LabelSSTRecord.sid:
|
||||||
// 字符串类型
|
// 字符串类型
|
||||||
@ -274,7 +298,7 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
if (null != sstRecord) {
|
if (null != sstRecord) {
|
||||||
value = sstRecord.getString(lsrec.getSSTIndex()).toString();
|
value = sstRecord.getString(lsrec.getSSTIndex()).toString();
|
||||||
}
|
}
|
||||||
addToRowCellList(lsrec.getColumn(), ObjectUtil.defaultIfNull(value, StrUtil.EMPTY));
|
addToRowCellList(lsrec, ObjectUtil.defaultIfNull(value, StrUtil.EMPTY));
|
||||||
break;
|
break;
|
||||||
case NumberRecord.sid: // 数字类型
|
case NumberRecord.sid: // 数字类型
|
||||||
final NumberRecord numrec = (NumberRecord) record;
|
final NumberRecord numrec = (NumberRecord) record;
|
||||||
@ -296,7 +320,7 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 向容器加入列值
|
// 向容器加入列值
|
||||||
addToRowCellList(numrec.getColumn(), value);
|
addToRowCellList(numrec, value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.hutool.poi.excel.sax;
|
package cn.hutool.poi.excel.sax;
|
||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.hutool.core.text.StrBuilder;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
||||||
import cn.hutool.poi.exceptions.POIException;
|
import cn.hutool.poi.exceptions.POIException;
|
||||||
@ -29,52 +30,39 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> implements ContentHandler {
|
public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> implements ContentHandler {
|
||||||
|
|
||||||
/**
|
|
||||||
* Cell单元格元素
|
|
||||||
*/
|
|
||||||
private static final String C_ELEMENT = "c";
|
|
||||||
/**
|
|
||||||
* 行元素
|
|
||||||
*/
|
|
||||||
private static final String ROW_ELEMENT = "row";
|
|
||||||
/**
|
|
||||||
* Cell中的行列号(Reference),行模式下此为行号属性名,列模式下为列号属性名
|
|
||||||
*/
|
|
||||||
private static final String R_ATTR = "r";
|
|
||||||
/**
|
|
||||||
* SST(SharedStringsTable) 的索引,样式index
|
|
||||||
*/
|
|
||||||
private static final String S_ATTR_VALUE = "s";
|
|
||||||
// 列中属性值
|
|
||||||
private static final String T_ATTR_VALUE = "t";
|
|
||||||
// sheet r:Id前缀
|
// sheet r:Id前缀
|
||||||
private static final String RID_PREFIX = "rId";
|
private static final String RID_PREFIX = "rId";
|
||||||
|
|
||||||
|
// 单元格的格式表,对应style.xml
|
||||||
|
private StylesTable stylesTable;
|
||||||
// excel 2007 的共享字符串表,对应sharedString.xml
|
// excel 2007 的共享字符串表,对应sharedString.xml
|
||||||
private SharedStringsTable sharedStringsTable;
|
private SharedStringsTable sharedStringsTable;
|
||||||
// 当前行
|
// sheet的索引
|
||||||
private int curRow;
|
private int sheetIndex;
|
||||||
|
|
||||||
|
// 当前非空行
|
||||||
|
private int index;
|
||||||
// 当前列
|
// 当前列
|
||||||
private int curCell;
|
private int curCell;
|
||||||
// 上一次的内容
|
|
||||||
private final StringBuilder lastContent = new StringBuilder(64);
|
|
||||||
// 单元数据类型
|
// 单元数据类型
|
||||||
private CellDataType cellDataType;
|
private CellDataType cellDataType;
|
||||||
|
// 当前行号,从0开始
|
||||||
|
private long rowNumber;
|
||||||
// 当前列坐标, 如A1,B5
|
// 当前列坐标, 如A1,B5
|
||||||
private String curCoordinate;
|
private String curCoordinate;
|
||||||
// 前一个列的坐标
|
// 前一个列的坐标
|
||||||
private String preCoordinate;
|
private String preCoordinate;
|
||||||
// 行的最大列坐标
|
// 行的最大列坐标
|
||||||
private String maxCellCoordinate;
|
private String maxCellCoordinate;
|
||||||
// 单元格的格式表,对应style.xml
|
// 单元格样式
|
||||||
private StylesTable stylesTable;
|
private XSSFCellStyle xssfCellStyle;
|
||||||
// 单元格存储的格式化字符串,nmtFmt的formatCode属性的值
|
// 单元格存储的格式化字符串,nmtFmt的formatCode属性的值
|
||||||
private String numFmtString;
|
private String numFmtString;
|
||||||
// sheet的索引
|
|
||||||
private int sheetIndex;
|
|
||||||
|
|
||||||
|
// 上一次的内容
|
||||||
|
private final StrBuilder lastContent = StrUtil.strBuilder();
|
||||||
// 存储每行的列元素
|
// 存储每行的列元素
|
||||||
List<Object> rowCellList = new ArrayList<>();
|
private List<Object> rowCellList = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 行处理器
|
* 行处理器
|
||||||
@ -136,9 +124,9 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
|||||||
final XSSFReader xssfReader = new XSSFReader(opcPackage);
|
final XSSFReader xssfReader = new XSSFReader(opcPackage);
|
||||||
|
|
||||||
// 获取共享样式表
|
// 获取共享样式表
|
||||||
try{
|
try {
|
||||||
stylesTable = xssfReader.getStylesTable();
|
stylesTable = xssfReader.getStylesTable();
|
||||||
} catch (Exception e){
|
} catch (Exception e) {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
// 获取共享字符串表
|
// 获取共享字符串表
|
||||||
@ -155,7 +143,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
|||||||
final Iterator<InputStream> sheetInputStreams = xssfReader.getSheetsData();
|
final Iterator<InputStream> sheetInputStreams = xssfReader.getSheetsData();
|
||||||
while (sheetInputStreams.hasNext()) {
|
while (sheetInputStreams.hasNext()) {
|
||||||
// 重新读取一个sheet时行归零
|
// 重新读取一个sheet时行归零
|
||||||
curRow = 0;
|
index = 0;
|
||||||
this.sheetIndex++;
|
this.sheetIndex++;
|
||||||
sheetInputStream = sheetInputStreams.next();
|
sheetInputStream = sheetInputStreams.next();
|
||||||
ExcelSaxUtil.readFrom(sheetInputStream, this);
|
ExcelSaxUtil.readFrom(sheetInputStream, this);
|
||||||
@ -178,24 +166,11 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||||
// 单元格元素
|
if (ElementName.row.match(localName)) {// 行开始
|
||||||
if (C_ELEMENT.equals(localName)) {
|
startRow(attributes);
|
||||||
// 获取当前列坐标
|
} else if (ElementName.c.match(localName)) {// 单元格元素
|
||||||
String tempCurCoordinate = attributes.getValue(R_ATTR);
|
startCell(attributes);
|
||||||
// 前一列为null,则将其设置为"@",A为第一列,ascii码为65,前一列即为@,ascii码64
|
|
||||||
if (preCoordinate == null) {
|
|
||||||
preCoordinate = String.valueOf(ExcelSaxUtil.CELL_FILL_CHAR);
|
|
||||||
} else {
|
|
||||||
// 存在,则前一列要设置为上一列的坐标
|
|
||||||
preCoordinate = curCoordinate;
|
|
||||||
}
|
}
|
||||||
// 重置当前列
|
|
||||||
curCoordinate = tempCurCoordinate;
|
|
||||||
// 设置单元格类型
|
|
||||||
setCellType(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastContent.setLength(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -203,42 +178,10 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void endElement(String uri, String localName, String qName) {
|
public void endElement(String uri, String localName, String qName) {
|
||||||
final String contentStr = StrUtil.trim(lastContent);
|
if (ElementName.c.match(localName)) { // 单元格结束
|
||||||
|
endCell();
|
||||||
// if (T_ELEMENT.equals(qName)) {
|
} else if (ElementName.row.match(localName)) {// 行结束
|
||||||
// // type标签
|
endRow();
|
||||||
// // rowCellList.add(curCell++, contentStr);
|
|
||||||
// } else
|
|
||||||
if (C_ELEMENT.equals(localName)) {
|
|
||||||
// cell标签
|
|
||||||
Object value = ExcelSaxUtil.getDataValue(this.cellDataType, contentStr, this.sharedStringsTable, this.numFmtString);
|
|
||||||
// 补全单元格之间的空格
|
|
||||||
fillBlankCell(preCoordinate, curCoordinate, false);
|
|
||||||
rowCellList.add(curCell++, value);
|
|
||||||
} else if (ROW_ELEMENT.equals(localName)) {
|
|
||||||
// 如果是row标签,说明已经到了一行的结尾
|
|
||||||
// 最大列坐标以第一行的为准
|
|
||||||
if (curRow == 0) {
|
|
||||||
maxCellCoordinate = curCoordinate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 补全一行尾部可能缺失的单元格
|
|
||||||
if (maxCellCoordinate != null) {
|
|
||||||
fillBlankCell(curCoordinate, maxCellCoordinate, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
rowHandler.handle(sheetIndex, curRow, rowCellList);
|
|
||||||
|
|
||||||
// 一行结束
|
|
||||||
// 新建一个新列,之前的列抛弃(可能被回收或rowHandler处理)
|
|
||||||
rowCellList = new ArrayList<>(curCell + 1);
|
|
||||||
// 行数增加
|
|
||||||
curRow++;
|
|
||||||
// 当前列置0
|
|
||||||
curCell = 0;
|
|
||||||
// 置空当前列坐标和前一列坐标
|
|
||||||
curCoordinate = null;
|
|
||||||
preCoordinate = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,6 +240,89 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
|||||||
// --------------------------------------------------------------------------------------- Pass method end
|
// --------------------------------------------------------------------------------------- Pass method end
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------- Private method start
|
// --------------------------------------------------------------------------------------- Private method start
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行开始
|
||||||
|
*
|
||||||
|
* @param attributes 属性列表
|
||||||
|
*/
|
||||||
|
private void startRow(Attributes attributes) {
|
||||||
|
this.rowNumber = Long.parseLong(AttributeName.r.getValue(attributes)) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单元格开始
|
||||||
|
*
|
||||||
|
* @param attributes 属性列表
|
||||||
|
*/
|
||||||
|
private void startCell(Attributes attributes) {
|
||||||
|
// 获取当前列坐标
|
||||||
|
final String tempCurCoordinate = AttributeName.r.getValue(attributes);
|
||||||
|
// 前一列为null,则将其设置为"@",A为第一列,ascii码为65,前一列即为@,ascii码64
|
||||||
|
if (preCoordinate == null) {
|
||||||
|
preCoordinate = String.valueOf(ExcelSaxUtil.CELL_FILL_CHAR);
|
||||||
|
} else {
|
||||||
|
// 存在,则前一列要设置为上一列的坐标
|
||||||
|
preCoordinate = curCoordinate;
|
||||||
|
}
|
||||||
|
// 重置当前列
|
||||||
|
curCoordinate = tempCurCoordinate;
|
||||||
|
// 设置单元格类型
|
||||||
|
setCellType(attributes);
|
||||||
|
|
||||||
|
// 清空之前的数据
|
||||||
|
lastContent.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个单元格结尾
|
||||||
|
*/
|
||||||
|
private void endCell() {
|
||||||
|
final String contentStr = StrUtil.trim(lastContent);
|
||||||
|
final Object value = ExcelSaxUtil.getDataValue(this.cellDataType, contentStr, this.sharedStringsTable, this.numFmtString);
|
||||||
|
// 补全单元格之间的空格
|
||||||
|
fillBlankCell(preCoordinate, curCoordinate, false);
|
||||||
|
addCellValue(curCell++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一行结尾
|
||||||
|
*/
|
||||||
|
private void endRow() {
|
||||||
|
// 最大列坐标以第一个非空行的为准
|
||||||
|
if (index == 0) {
|
||||||
|
maxCellCoordinate = curCoordinate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 补全一行尾部可能缺失的单元格
|
||||||
|
if (maxCellCoordinate != null) {
|
||||||
|
fillBlankCell(curCoordinate, maxCellCoordinate, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowHandler.handle(sheetIndex, rowNumber, rowCellList);
|
||||||
|
|
||||||
|
// 一行结束
|
||||||
|
// 新建一个新列,之前的列抛弃(可能被回收或rowHandler处理)
|
||||||
|
rowCellList = new ArrayList<>(curCell + 1);
|
||||||
|
// 行数增加
|
||||||
|
index++;
|
||||||
|
// 当前列置0
|
||||||
|
curCell = 0;
|
||||||
|
// 置空当前列坐标和前一列坐标
|
||||||
|
curCoordinate = null;
|
||||||
|
preCoordinate = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在一行中的指定列增加值
|
||||||
|
* @param index 位置
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
private void addCellValue(int index, Object value){
|
||||||
|
this.rowCellList.add(index, value);
|
||||||
|
this.rowHandler.handleCell(this.sheetIndex, this.rowNumber, index, value, this.xssfCellStyle);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 填充空白单元格,如果前一个单元格大于后一个,不需要填充<br>
|
* 填充空白单元格,如果前一个单元格大于后一个,不需要填充<br>
|
||||||
*
|
*
|
||||||
@ -311,7 +337,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
|||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
rowCellList.add(curCell++, "");
|
addCellValue(curCell++, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,19 +345,19 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
|||||||
/**
|
/**
|
||||||
* 设置单元格的类型
|
* 设置单元格的类型
|
||||||
*
|
*
|
||||||
* @param attribute 属性
|
* @param attributes 属性
|
||||||
*/
|
*/
|
||||||
private void setCellType(Attributes attribute) {
|
private void setCellType(Attributes attributes) {
|
||||||
// numFmtString的值
|
// numFmtString的值
|
||||||
numFmtString = "";
|
numFmtString = "";
|
||||||
this.cellDataType = CellDataType.of(attribute.getValue(T_ATTR_VALUE));
|
this.cellDataType = CellDataType.of(AttributeName.t.getValue(attributes));
|
||||||
|
|
||||||
// 获取单元格的xf索引,对应style.xml中cellXfs的子元素xf
|
// 获取单元格的xf索引,对应style.xml中cellXfs的子元素xf
|
||||||
if(null != this.stylesTable){
|
if (null != this.stylesTable) {
|
||||||
final String xfIndexStr = attribute.getValue(S_ATTR_VALUE);
|
final String xfIndexStr = AttributeName.s.getValue(attributes);
|
||||||
if (null != xfIndexStr) {
|
if (null != xfIndexStr) {
|
||||||
int xfIndex = Integer.parseInt(xfIndexStr);
|
int xfIndex = Integer.parseInt(xfIndexStr);
|
||||||
final XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(xfIndex);
|
this.xssfCellStyle = stylesTable.getStyleAt(xfIndex);
|
||||||
numFmtString = xssfCellStyle.getDataFormatString();
|
numFmtString = xssfCellStyle.getDataFormatString();
|
||||||
// 单元格存储格式的索引,对应style.xml中的numFmts元素的子元素索引
|
// 单元格存储格式的索引,对应style.xml中的numFmts元素的子元素索引
|
||||||
int numFmtIndex = xssfCellStyle.getDataFormat();
|
int numFmtIndex = xssfCellStyle.getDataFormat();
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package cn.hutool.poi.excel.sax.handler;
|
package cn.hutool.poi.excel.sax.handler;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,10 +13,22 @@ import java.util.List;
|
|||||||
public interface RowHandler {
|
public interface RowHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理一行数据
|
* 处理一个单元格的数据
|
||||||
* @param sheetIndex 当前Sheet序号
|
* @param sheetIndex 当前Sheet序号
|
||||||
* @param rowIndex 当前行号
|
* @param rowIndex 当前行号
|
||||||
|
* @param cellIndex 当前列号
|
||||||
|
* @param value 单元格的值
|
||||||
|
* @param xssfCellStyle 单元格样式
|
||||||
|
*/
|
||||||
|
default void handleCell(int sheetIndex, long rowIndex, int cellIndex, Object value, CellStyle xssfCellStyle){
|
||||||
|
//pass
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理一行数据
|
||||||
|
* @param sheetIndex 当前Sheet序号
|
||||||
|
* @param rowIndex 当前行号,从0开始计数
|
||||||
* @param rowList 行数据列表
|
* @param rowList 行数据列表
|
||||||
*/
|
*/
|
||||||
void handle(int sheetIndex, int rowIndex, List<Object> rowList);
|
void handle(int sheetIndex, long rowIndex, List<Object> rowList);
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,17 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.poi.excel.ExcelUtil;
|
import cn.hutool.poi.excel.ExcelUtil;
|
||||||
import cn.hutool.poi.excel.sax.Excel03SaxReader;
|
import cn.hutool.poi.excel.sax.Excel03SaxReader;
|
||||||
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
||||||
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Excel sax方式读取
|
* Excel sax方式读取
|
||||||
*
|
*
|
||||||
* @author looly
|
* @author looly
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class ExcelSaxReadTest {
|
public class ExcelSaxReadTest {
|
||||||
|
|
||||||
@ -64,4 +66,39 @@ public class ExcelSaxReadTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void handle07CellTest() {
|
||||||
|
ExcelUtil.readBySax("d:/test/test.xlsx", -1, new RowHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCell(int sheetIndex, long rowIndex, int cellIndex, Object value, CellStyle xssfCellStyle) {
|
||||||
|
Console.log("{} {} {}", rowIndex, cellIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(int sheetIndex, long rowIndex, List<Object> rowList) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void handle03CellTest() {
|
||||||
|
ExcelUtil.readBySax("d:/test/test.xls", -1, new RowHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCell(int sheetIndex, long rowIndex, int cellIndex, Object value, CellStyle xssfCellStyle) {
|
||||||
|
Console.log("{} {} {}", rowIndex, cellIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(int sheetIndex, long rowIndex, List<Object> rowList) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user