mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-02 20:02:49 +08:00
add sheetId support
This commit is contained in:
parent
a508533f9c
commit
60efd24469
@ -31,6 +31,7 @@
|
||||
* 【core 】 NumberUtil.factorial注释明确(pr#1126@Github)
|
||||
* 【core 】 NumberUtil增加isPowerOfTwo方法(pr#1132@Github)
|
||||
* 【core 】 优化BooleanUtil的校验逻辑(pr#1137@Github)
|
||||
* 【poi 】 改进sax方式读取逻辑,支持sheetId(issue#1141@Github)
|
||||
|
||||
### Bug修复
|
||||
* 【crypto 】 修复SM2验签后无法解密问题(issue#I1W0VP@Gitee)
|
||||
|
@ -1,9 +1,10 @@
|
||||
package cn.hutool.poi.excel;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@ -48,11 +49,24 @@ public class ExcelFileUtil {
|
||||
* @return 是否为XLSX格式的Excel文件(XSSF)
|
||||
*/
|
||||
public static boolean isXlsx(InputStream in) {
|
||||
if (false == in.markSupported()) {
|
||||
in = new BufferedInputStream(in);
|
||||
}
|
||||
try {
|
||||
return FileMagic.valueOf(in) == FileMagic.OOXML;
|
||||
return FileMagic.valueOf(IoUtil.toMarkSupportStream(in)) == FileMagic.OOXML;
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为XLSX格式的Excel文件(XSSF)<br>
|
||||
* XLSX文件主要用于Excel 2007+创建
|
||||
*
|
||||
* @param file excel文件
|
||||
* @return 是否为XLSX格式的Excel文件(XSSF)
|
||||
* @since 5.4.4
|
||||
*/
|
||||
public static boolean isXlsx(File file) {
|
||||
try {
|
||||
return FileMagic.valueOf(file) == FileMagic.OOXML;
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import cn.hutool.poi.excel.sax.Excel03SaxReader;
|
||||
import cn.hutool.poi.excel.sax.Excel07SaxReader;
|
||||
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
@ -34,13 +33,7 @@ public class ExcelUtil {
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static void readBySax(String path, int sheetIndex, RowHandler rowHandler) {
|
||||
BufferedInputStream in = null;
|
||||
try {
|
||||
in = FileUtil.getInputStream(path);
|
||||
readBySax(in, sheetIndex, rowHandler);
|
||||
} finally {
|
||||
IoUtil.close(in);
|
||||
}
|
||||
readBySax(FileUtil.file(path), sheetIndex, rowHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,12 +45,10 @@ public class ExcelUtil {
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static void readBySax(File file, int sheetIndex, RowHandler rowHandler) {
|
||||
BufferedInputStream in = null;
|
||||
try {
|
||||
in = FileUtil.getInputStream(file);
|
||||
readBySax(in, sheetIndex, rowHandler);
|
||||
} finally {
|
||||
IoUtil.close(in);
|
||||
if (ExcelFileUtil.isXlsx(file)) {
|
||||
read07BySax(file, sheetIndex, rowHandler);
|
||||
} else {
|
||||
read03BySax(file, sheetIndex, rowHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,38 +0,0 @@
|
||||
package cn.hutool.poi.excel.sax;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.poi.exceptions.POIException;
|
||||
|
||||
/**
|
||||
* 抽象的Sax方式Excel读取器,提供一些共用方法
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
* @param <T> 子对象类型,用于标记返回值this
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public abstract class AbstractExcelSaxReader<T> implements ExcelSaxReader<T> {
|
||||
|
||||
@Override
|
||||
public T read(String path) throws POIException {
|
||||
return read(FileUtil.file(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(File file) throws POIException {
|
||||
return read(file, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(InputStream in) throws POIException {
|
||||
return read(in, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(String path, int sheetIndex) throws POIException {
|
||||
return read(FileUtil.file(path), sheetIndex);
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> implements HSSFListener {
|
||||
public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03SaxReader> {
|
||||
|
||||
/**
|
||||
* 如果为公式,true表示输出公式计算后的结果值,false表示输出公式本身
|
||||
@ -83,18 +83,18 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
||||
|
||||
// ------------------------------------------------------------------------------ Read start
|
||||
@Override
|
||||
public Excel03SaxReader read(File file, int rid) throws POIException {
|
||||
public Excel03SaxReader read(File file, String idOrRid) throws POIException {
|
||||
try {
|
||||
return read(new POIFSFileSystem(file), rid);
|
||||
return read(new POIFSFileSystem(file), idOrRid);
|
||||
} catch (IOException e) {
|
||||
throw new POIException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Excel03SaxReader read(InputStream excelStream, int rid) throws POIException {
|
||||
public Excel03SaxReader read(InputStream excelStream, String idOrRid) throws POIException {
|
||||
try {
|
||||
return read(new POIFSFileSystem(excelStream), rid);
|
||||
return read(new POIFSFileSystem(excelStream), idOrRid);
|
||||
} catch (IOException e) {
|
||||
throw new POIException(e);
|
||||
}
|
||||
@ -104,12 +104,12 @@ public class Excel03SaxReader extends AbstractExcelSaxReader<Excel03SaxReader> i
|
||||
* 读取
|
||||
*
|
||||
* @param fs {@link POIFSFileSystem}
|
||||
* @param rid sheet序号
|
||||
* @param id sheet序号
|
||||
* @return this
|
||||
* @throws POIException IO异常包装
|
||||
*/
|
||||
public Excel03SaxReader read(POIFSFileSystem fs, int rid) throws POIException {
|
||||
this.rid = rid;
|
||||
public Excel03SaxReader read(POIFSFileSystem fs, String id) throws POIException {
|
||||
this.rid = Integer.parseInt(id);
|
||||
|
||||
formatListener = new FormatTrackingHSSFListener(new MissingRecordAwareHSSFListener(this));
|
||||
final HSSFRequest request = new HSSFRequest();
|
||||
|
@ -1,10 +1,14 @@
|
||||
package cn.hutool.poi.excel.sax;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
||||
import cn.hutool.poi.exceptions.POIException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
import org.apache.poi.ss.usermodel.BuiltinFormats;
|
||||
import org.apache.poi.xssf.eventusermodel.XSSFReader;
|
||||
@ -12,10 +16,10 @@ import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.model.StylesTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@ -28,7 +32,7 @@ import java.util.List;
|
||||
* @author Looly
|
||||
* @since 3.1.2
|
||||
*/
|
||||
public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> implements ContentHandler {
|
||||
public class Excel07SaxReader extends DefaultHandler implements ExcelSaxReader<Excel07SaxReader> {
|
||||
|
||||
// sheet r:Id前缀
|
||||
private static final String RID_PREFIX = "rId";
|
||||
@ -92,20 +96,30 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
||||
// ------------------------------------------------------------------------------ Read start
|
||||
@Override
|
||||
public Excel07SaxReader read(File file, int rid) throws POIException {
|
||||
return read(file, RID_PREFIX + rid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Excel07SaxReader read(File file, String idOrRid) throws POIException {
|
||||
try {
|
||||
return read(OPCPackage.open(file), rid);
|
||||
} catch (Exception e) {
|
||||
return read(OPCPackage.open(file), idOrRid);
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new POIException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Excel07SaxReader read(InputStream in, int rid) throws POIException {
|
||||
try {
|
||||
return read(OPCPackage.open(in), rid);
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
return read(in, RID_PREFIX + rid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Excel07SaxReader read(InputStream in, String idOrRid) throws POIException {
|
||||
try (final OPCPackage opcPackage = OPCPackage.open(in)) {
|
||||
return read(opcPackage, idOrRid);
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new POIException(e);
|
||||
}
|
||||
}
|
||||
@ -113,53 +127,60 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
||||
/**
|
||||
* 开始读取Excel,Sheet编号从0开始计数
|
||||
*
|
||||
* @param opcPackage {@link OPCPackage},Excel包
|
||||
* @param opcPackage {@link OPCPackage},Excel包,读取后不关闭
|
||||
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
public Excel07SaxReader read(OPCPackage opcPackage, int rid) throws POIException {
|
||||
InputStream sheetInputStream = null;
|
||||
return read(opcPackage, RID_PREFIX + rid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel,Sheet编号从0开始计数
|
||||
*
|
||||
* @param opcPackage {@link OPCPackage},Excel包,读取后不关闭
|
||||
* @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
public Excel07SaxReader read(OPCPackage opcPackage, String idOrRid) throws POIException {
|
||||
try {
|
||||
final XSSFReader xssfReader = new XSSFReader(opcPackage);
|
||||
|
||||
// 获取共享样式表
|
||||
try {
|
||||
stylesTable = xssfReader.getStylesTable();
|
||||
} catch (Exception e) {
|
||||
//ignore
|
||||
}
|
||||
// 获取共享字符串表
|
||||
this.sharedStringsTable = xssfReader.getSharedStringsTable();
|
||||
|
||||
if (rid > -1) {
|
||||
this.sheetIndex = rid;
|
||||
// 根据 rId# 或 rSheet# 查找sheet
|
||||
sheetInputStream = xssfReader.getSheet(RID_PREFIX + (rid + 1));
|
||||
ExcelSaxUtil.readFrom(sheetInputStream, this);
|
||||
rowHandler.doAfterAllAnalysed();
|
||||
} else {
|
||||
this.sheetIndex = -1;
|
||||
// 遍历所有sheet
|
||||
final Iterator<InputStream> sheetInputStreams = xssfReader.getSheetsData();
|
||||
while (sheetInputStreams.hasNext()) {
|
||||
// 重新读取一个sheet时行归零
|
||||
index = 0;
|
||||
this.sheetIndex++;
|
||||
sheetInputStream = sheetInputStreams.next();
|
||||
ExcelSaxUtil.readFrom(sheetInputStream, this);
|
||||
rowHandler.doAfterAllAnalysed();
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
return read(new XSSFReader(opcPackage), idOrRid);
|
||||
} catch (OpenXML4JException e) {
|
||||
throw new POIException(e);
|
||||
} finally {
|
||||
IoUtil.close(sheetInputStream);
|
||||
IoUtil.close(opcPackage);
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel,Sheet编号从0开始计数
|
||||
*
|
||||
* @param xssfReader {@link XSSFReader},Excel读取器
|
||||
* @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
* @since 5.4.4
|
||||
*/
|
||||
public Excel07SaxReader read(XSSFReader xssfReader, String idOrRid) throws POIException {
|
||||
// 获取共享样式表
|
||||
try {
|
||||
stylesTable = xssfReader.getStylesTable();
|
||||
} catch (Exception e) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
// 获取共享字符串表
|
||||
try {
|
||||
this.sharedStringsTable = xssfReader.getSharedStringsTable();
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new POIException(e);
|
||||
}
|
||||
|
||||
return readSheets(xssfReader, idOrRid);
|
||||
}
|
||||
// ------------------------------------------------------------------------------ Read end
|
||||
|
||||
@ -196,53 +217,57 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
||||
lastContent.append(ch, start, length);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------- Pass method start
|
||||
@Override
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
// pass
|
||||
}
|
||||
// --------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* ?xml标签的回调处理方法
|
||||
* 开始读取Excel,Sheet编号从0开始计数
|
||||
*
|
||||
* @param xssfReader {@link XSSFReader},Excel读取器
|
||||
* @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId0,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
* @since 5.4.4
|
||||
*/
|
||||
@Override
|
||||
public void startDocument() {
|
||||
// pass
|
||||
private Excel07SaxReader readSheets(XSSFReader xssfReader, String idOrRid) throws POIException {
|
||||
// 将sheetId转换为rid
|
||||
if (NumberUtil.isInteger(idOrRid)) {
|
||||
final SheetRidReader ridReader = new SheetRidReader();
|
||||
final String rid = ridReader.read(xssfReader).getRidBySheetId(idOrRid);
|
||||
if (StrUtil.isNotEmpty(rid)) {
|
||||
idOrRid = rid;
|
||||
}
|
||||
}
|
||||
this.sheetIndex = Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRid, RID_PREFIX));
|
||||
InputStream sheetInputStream = null;
|
||||
try {
|
||||
if (this.sheetIndex > -1) {
|
||||
// 根据 rId# 或 rSheet# 查找sheet
|
||||
sheetInputStream = xssfReader.getSheet(RID_PREFIX + (this.sheetIndex + 1));
|
||||
ExcelSaxUtil.readFrom(sheetInputStream, this);
|
||||
rowHandler.doAfterAllAnalysed();
|
||||
} else {
|
||||
this.sheetIndex = -1;
|
||||
// 遍历所有sheet
|
||||
final Iterator<InputStream> sheetInputStreams = xssfReader.getSheetsData();
|
||||
while (sheetInputStreams.hasNext()) {
|
||||
// 重新读取一个sheet时行归零
|
||||
index = 0;
|
||||
this.sheetIndex++;
|
||||
sheetInputStream = sheetInputStreams.next();
|
||||
ExcelSaxUtil.readFrom(sheetInputStream, this);
|
||||
rowHandler.doAfterAllAnalysed();
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new POIException(e);
|
||||
} finally {
|
||||
IoUtil.close(sheetInputStream);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endDocument() {
|
||||
// pass
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrefixMapping(String prefix, String uri) {
|
||||
// pass
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endPrefixMapping(String prefix) {
|
||||
// pass
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignorableWhitespace(char[] ch, int start, int length) {
|
||||
// pass
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processingInstruction(String target, String data) {
|
||||
// pass
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skippedEntity(String name) {
|
||||
// pass
|
||||
}
|
||||
// --------------------------------------------------------------------------------------- Pass method end
|
||||
|
||||
// --------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 行开始
|
||||
*
|
||||
@ -317,10 +342,11 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
|
||||
|
||||
/**
|
||||
* 在一行中的指定列增加值
|
||||
*
|
||||
* @param index 位置
|
||||
* @param value 值
|
||||
*/
|
||||
private void addCellValue(int index, Object value){
|
||||
private void addCellValue(int index, Object value) {
|
||||
this.rowCellList.add(index, value);
|
||||
this.rowHandler.handleCell(this.sheetIndex, this.rowNumber, index, value, this.xssfCellStyle);
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
package cn.hutool.poi.excel.sax;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.poi.exceptions.POIException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
import cn.hutool.poi.exceptions.POIException;
|
||||
|
||||
/**
|
||||
* Sax方式读取Excel接口,提供一些共用方法
|
||||
* @author looly
|
||||
@ -13,60 +14,105 @@ import cn.hutool.poi.exceptions.POIException;
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public interface ExcelSaxReader<T> {
|
||||
|
||||
/**
|
||||
* 开始读取Excel
|
||||
*
|
||||
* @param file Excel文件
|
||||
* @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(File file, String idOrRid) throws POIException;
|
||||
|
||||
/**
|
||||
* 开始读取Excel,读取结束后并不关闭流
|
||||
*
|
||||
* @param in Excel流
|
||||
* @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(InputStream in, String idOrRid) throws POIException;
|
||||
|
||||
/**
|
||||
* 开始读取Excel,读取所有sheet
|
||||
*
|
||||
*
|
||||
* @param path Excel文件路径
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(String path) throws POIException;
|
||||
default T read(String path) throws POIException {
|
||||
return read(FileUtil.file(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel,读取所有sheet
|
||||
*
|
||||
*
|
||||
* @param file Excel文件
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(File file) throws POIException;
|
||||
default T read(File file) throws POIException {
|
||||
return read(file, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel,读取所有sheet,读取结束后并不关闭流
|
||||
*
|
||||
*
|
||||
* @param in Excel包流
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(InputStream in) throws POIException;
|
||||
default T read(InputStream in) throws POIException {
|
||||
return read(in, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel
|
||||
*
|
||||
*
|
||||
* @param path 文件路径
|
||||
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(String path, int rid) throws POIException;
|
||||
default T read(String path, int rid) throws POIException {
|
||||
return read(FileUtil.file(path), rid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel
|
||||
*
|
||||
*
|
||||
* @param path 文件路径
|
||||
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
default T read(String path, String rid) throws POIException {
|
||||
return read(FileUtil.file(path), rid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel
|
||||
*
|
||||
* @param file Excel文件
|
||||
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(File file, int rid) throws POIException;
|
||||
default T read(File file, int rid) throws POIException{
|
||||
return read(file, String.valueOf(rid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取Excel,读取结束后并不关闭流
|
||||
*
|
||||
*
|
||||
* @param in Excel流
|
||||
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
|
||||
* @return this
|
||||
* @throws POIException POI异常
|
||||
*/
|
||||
T read(InputStream in, int rid) throws POIException;
|
||||
default T read(InputStream in, int rid) throws POIException{
|
||||
return read(in, String.valueOf(rid));
|
||||
};
|
||||
}
|
||||
|
@ -73,9 +73,9 @@ public class ExcelSaxUtil {
|
||||
}
|
||||
break;
|
||||
case NUMBER:
|
||||
try{
|
||||
try {
|
||||
result = getNumberValue(value, numFmtString);
|
||||
}catch (NumberFormatException e){
|
||||
} catch (NumberFormatException e) {
|
||||
result = value;
|
||||
}
|
||||
break;
|
||||
@ -150,6 +150,7 @@ public class ExcelSaxUtil {
|
||||
public static void readFrom(InputStream xmlDocStream, ContentHandler handler) throws DependencyException, POIException, IORuntimeException {
|
||||
XMLReader xmlReader;
|
||||
try {
|
||||
// xmlReader = XMLReaderFactory.createXMLReader();
|
||||
//noinspection deprecation
|
||||
xmlReader = SAXHelper.newXMLReader();
|
||||
} catch (SAXException | ParserConfigurationException e) {
|
||||
|
@ -0,0 +1,110 @@
|
||||
package cn.hutool.poi.excel.sax;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.poi.exceptions.POIException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.xssf.eventusermodel.XSSFReader;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 在Sax方式读取Excel时,读取sheet标签中sheetId和rid的对应关系,类似于:
|
||||
* <pre>
|
||||
* <sheet name="Sheet6" sheetId="4" r:id="6"/>
|
||||
* </pre>
|
||||
*
|
||||
* 读取结果为:
|
||||
*
|
||||
* <pre>
|
||||
* {"4": "6"}
|
||||
* </pre>
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.4.4
|
||||
*/
|
||||
public class SheetRidReader extends DefaultHandler {
|
||||
|
||||
private final static String TAG_NAME = "sheet";
|
||||
private final static String RID_ATTR = "r:id";
|
||||
private final static String SHEET_ID_ATTR = "sheetId";
|
||||
private final static String NAME_ATTR = "name";
|
||||
|
||||
private final Map<String, String> ID_RID_MAP = new HashMap<>();
|
||||
private final Map<String, String> NAME_RID_MAP = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 读取Wordkbook的XML中sheet标签中sheetId和rid的对应关系
|
||||
*
|
||||
* @param xssfReader XSSF读取器
|
||||
*/
|
||||
public SheetRidReader read(XSSFReader xssfReader){
|
||||
InputStream workbookData = null;
|
||||
try{
|
||||
workbookData = xssfReader.getWorkbookData();
|
||||
ExcelSaxUtil.readFrom(workbookData, this);
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new POIException(e);
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
} finally {
|
||||
IoUtil.close(workbookData);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sheetId获取rid
|
||||
*
|
||||
* @param sheetId Sheet的ID
|
||||
* @return rid
|
||||
*/
|
||||
public String getRidBySheetId(String sheetId){
|
||||
return ID_RID_MAP.get(sheetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sheet name获取rid
|
||||
*
|
||||
* @param sheetName Sheet的name
|
||||
* @return rid
|
||||
*/
|
||||
public String getRidByName(String sheetName){
|
||||
return NAME_RID_MAP.get(sheetName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
if(TAG_NAME.equalsIgnoreCase(localName)){
|
||||
final int length = attributes.getLength();
|
||||
String sheetId = null;
|
||||
String rid = null;
|
||||
String name = null;
|
||||
for (int i = 0; i < length; i++) {
|
||||
switch (attributes.getLocalName(i)){
|
||||
case SHEET_ID_ATTR:
|
||||
sheetId = attributes.getValue(i);
|
||||
break;
|
||||
case RID_ATTR:
|
||||
rid = attributes.getValue(i);
|
||||
break;
|
||||
case NAME_ATTR:
|
||||
name = attributes.getValue(i);
|
||||
break;
|
||||
}
|
||||
if(StrUtil.isNotEmpty(sheetId)){
|
||||
ID_RID_MAP.put(sheetId, rid);
|
||||
}
|
||||
if(StrUtil.isNotEmpty(name)){
|
||||
NAME_RID_MAP.put(name, rid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user