Browse Source

修复读取excel可能异常的bug

developing
Jiaju Zhuang 3 years ago
parent
commit
5aaba749ac
  1. 65
      src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java
  2. 13
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java
  3. 55
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java
  4. 29
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java
  5. 10
      src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java
  6. 2
      src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java
  7. 2
      src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java
  8. 31
      src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java

65
src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java

@ -1,13 +1,6 @@
package com.alibaba.excel.analysis.v07.handlers; package com.alibaba.excel.analysis.v07.handlers;
import java.math.BigDecimal;
import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.StringUtils;
/** /**
* Cell Value Handler * Cell Value Handler
@ -16,67 +9,9 @@ import com.alibaba.excel.util.StringUtils;
*/ */
public abstract class AbstractCellValueTagHandler extends AbstractXlsxTagHandler { public abstract class AbstractCellValueTagHandler extends AbstractXlsxTagHandler {
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
ReadCellData<?> tempCellData = xlsxReadSheetHolder.getTempCellData();
StringBuilder tempData = xlsxReadSheetHolder.getTempData();
String tempDataString = tempData.toString();
CellDataTypeEnum oldType = tempCellData.getType();
switch (oldType) {
case DIRECT_STRING:
case STRING:
case ERROR:
tempCellData.setStringValue(tempData.toString());
break;
case BOOLEAN:
if (StringUtils.isEmpty(tempDataString)) {
tempCellData.setType(CellDataTypeEnum.EMPTY);
break;
}
tempCellData.setBooleanValue(BooleanUtils.valueOf(tempData.toString()));
break;
case NUMBER:
case EMPTY:
if (StringUtils.isEmpty(tempDataString)) {
tempCellData.setType(CellDataTypeEnum.EMPTY);
break;
}
// fix https://github.com/alibaba/easyexcel/issues/1595
if (StringUtils.isNumeric(tempDataString)) {
tempCellData.setType(CellDataTypeEnum.NUMBER);
tempCellData.setNumberValue(BigDecimal.valueOf(Double.parseDouble(tempDataString)));
} else {
tempCellData.setType(CellDataTypeEnum.STRING);
tempCellData.setStringValue(tempData.toString());
}
break;
default:
throw new IllegalStateException("Cannot set values now");
}
// set string value
setStringValue(xlsxReadContext);
if (tempCellData.getStringValue() != null
&& xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
tempCellData.setStringValue(tempCellData.getStringValue().trim());
}
tempCellData.checkEmpty();
xlsxReadSheetHolder.getCellMap().put(xlsxReadSheetHolder.getColumnIndex(), tempCellData);
}
@Override @Override
public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) { public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) {
xlsxReadContext.xlsxReadSheetHolder().getTempData().append(ch, start, length); xlsxReadContext.xlsxReadSheetHolder().getTempData().append(ch, start, length);
} }
/**
* Set string value.
*
* @param xlsxReadContext
*/
protected abstract void setStringValue(XlsxReadContext xlsxReadContext);
} }

13
src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java

@ -1,10 +1,5 @@
package com.alibaba.excel.analysis.v07.handlers; package com.alibaba.excel.analysis.v07.handlers;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.metadata.data.CellData;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
/** /**
* Cell inline string value handler * Cell inline string value handler
* *
@ -12,12 +7,4 @@ import org.apache.poi.xssf.usermodel.XSSFRichTextString;
*/ */
public class CellInlineStringValueTagHandler extends AbstractCellValueTagHandler { public class CellInlineStringValueTagHandler extends AbstractCellValueTagHandler {
@Override
protected void setStringValue(XlsxReadContext xlsxReadContext) {
// This is a special form of string
CellData<?> tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData();
XSSFRichTextString richTextString = new XSSFRichTextString(tempCellData.getStringValue());
tempCellData.setStringValue(richTextString.toString());
}
} }

55
src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java

@ -1,5 +1,7 @@
package com.alibaba.excel.analysis.v07.handlers; package com.alibaba.excel.analysis.v07.handlers;
import java.math.BigDecimal;
import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.context.xlsx.XlsxReadContext;
@ -7,6 +9,7 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.PositionUtils; import com.alibaba.excel.util.PositionUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
@ -31,7 +34,7 @@ public class CellTagHandler extends AbstractXlsxTagHandler {
// t="s" ,it means String // t="s" ,it means String
// t="str" ,it means String,but does not need to be read in the 'sharedStrings.xml' // t="str" ,it means String,but does not need to be read in the 'sharedStrings.xml'
// t="inlineStr" ,it means String // t="inlineStr" ,it means String,but does not need to be read in the 'sharedStrings.xml'
// t="b" ,it means Boolean // t="b" ,it means Boolean
// t="e" ,it means Error // t="e" ,it means Error
// t="n" ,it means Number // t="n" ,it means Number
@ -61,4 +64,54 @@ public class CellTagHandler extends AbstractXlsxTagHandler {
xlsxReadSheetHolder.getTempCellData().setDataFormatData(dataFormatData); xlsxReadSheetHolder.getTempCellData().setDataFormatData(dataFormatData);
} }
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
ReadCellData<?> tempCellData = xlsxReadSheetHolder.getTempCellData();
StringBuilder tempData = xlsxReadSheetHolder.getTempData();
String tempDataString = tempData.toString();
CellDataTypeEnum oldType = tempCellData.getType();
switch (oldType) {
case STRING:
// In some cases, although cell type is a string, it may be an empty tag
if (StringUtils.isEmpty(tempCellData.getStringValue())) {
break;
}
String stringValue = xlsxReadContext.readWorkbookHolder().getReadCache()
.get(Integer.valueOf(tempCellData.getStringValue()));
tempCellData.setStringValue(stringValue);
break;
case DIRECT_STRING:
case ERROR:
tempCellData.setStringValue(tempData.toString());
tempCellData.setType(CellDataTypeEnum.STRING);
break;
case BOOLEAN:
if (StringUtils.isEmpty(tempDataString)) {
tempCellData.setType(CellDataTypeEnum.EMPTY);
break;
}
tempCellData.setBooleanValue(BooleanUtils.valueOf(tempData.toString()));
break;
case NUMBER:
case EMPTY:
if (StringUtils.isEmpty(tempDataString)) {
tempCellData.setType(CellDataTypeEnum.EMPTY);
break;
}
tempCellData.setType(CellDataTypeEnum.NUMBER);
tempCellData.setNumberValue(BigDecimal.valueOf(Double.parseDouble(tempDataString)));
break;
default:
throw new IllegalStateException("Cannot set values now");
}
if (tempCellData.getStringValue() != null
&& xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
tempCellData.setStringValue(tempCellData.getStringValue().trim());
}
tempCellData.checkEmpty();
xlsxReadSheetHolder.getCellMap().put(xlsxReadSheetHolder.getColumnIndex(), tempCellData);
}
} }

29
src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java

@ -1,10 +1,5 @@
package com.alibaba.excel.analysis.v07.handlers; package com.alibaba.excel.analysis.v07.handlers;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.util.StringUtils;
/** /**
* Cell Value Handler * Cell Value Handler
* *
@ -12,28 +7,4 @@ import com.alibaba.excel.util.StringUtils;
*/ */
public class CellValueTagHandler extends AbstractCellValueTagHandler { public class CellValueTagHandler extends AbstractCellValueTagHandler {
@Override
protected void setStringValue(XlsxReadContext xlsxReadContext) {
// Have to go "sharedStrings.xml" and get it
CellData tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData();
switch (tempCellData.getType()) {
case STRING:
// In some cases, although cell type is a string, it may be an empty tag
if(StringUtils.isEmpty(tempCellData.getStringValue())){
break;
}
String stringValue = xlsxReadContext.readWorkbookHolder().getReadCache()
.get(Integer.valueOf(tempCellData.getStringValue()));
if (stringValue != null && xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
stringValue = stringValue.trim();
}
tempCellData.setStringValue(stringValue);
break;
case DIRECT_STRING:
tempCellData.setType(CellDataTypeEnum.STRING);
break;
default:
}
}
} }

10
src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java

@ -3,10 +3,6 @@ package com.alibaba.excel.analysis.v07.handlers.sax;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.alibaba.excel.analysis.v07.handlers.CellFormulaTagHandler; import com.alibaba.excel.analysis.v07.handlers.CellFormulaTagHandler;
import com.alibaba.excel.analysis.v07.handlers.CellInlineStringValueTagHandler; import com.alibaba.excel.analysis.v07.handlers.CellInlineStringValueTagHandler;
import com.alibaba.excel.analysis.v07.handlers.CellTagHandler; import com.alibaba.excel.analysis.v07.handlers.CellTagHandler;
@ -19,9 +15,15 @@ import com.alibaba.excel.analysis.v07.handlers.XlsxTagHandler;
import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.context.xlsx.XlsxReadContext;
import lombok.extern.slf4j.Slf4j;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/** /**
* @author jipengfei * @author jipengfei
*/ */
@Slf4j
public class XlsxRowHandler extends DefaultHandler { public class XlsxRowHandler extends DefaultHandler {
private XlsxReadContext xlsxReadContext; private XlsxReadContext xlsxReadContext;
private static final Map<String, XlsxTagHandler> XLSX_CELL_HANDLER_MAP = new HashMap<String, XlsxTagHandler>(32); private static final Map<String, XlsxTagHandler> XLSX_CELL_HANDLER_MAP = new HashMap<String, XlsxTagHandler>(32);

2
src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java

@ -51,7 +51,7 @@ public enum CellDataTypeEnum {
static { static {
TYPE_ROUTING_MAP.put("s", STRING); TYPE_ROUTING_MAP.put("s", STRING);
TYPE_ROUTING_MAP.put("str", DIRECT_STRING); TYPE_ROUTING_MAP.put("str", DIRECT_STRING);
TYPE_ROUTING_MAP.put("inlineStr", STRING); TYPE_ROUTING_MAP.put("inlineStr", DIRECT_STRING);
TYPE_ROUTING_MAP.put("e", ERROR); TYPE_ROUTING_MAP.put("e", ERROR);
TYPE_ROUTING_MAP.put("b", BOOLEAN); TYPE_ROUTING_MAP.put("b", BOOLEAN);
TYPE_ROUTING_MAP.put("n", NUMBER); TYPE_ROUTING_MAP.put("n", NUMBER);

2
src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java

@ -36,7 +36,7 @@ public class Lock2Test {
public void test() throws Exception { public void test() throws Exception {
File file = TestFileUtil.readUserHomeFile("test/test4.xlsx"); File file = TestFileUtil.readUserHomeFile("test/test4.xlsx");
List<Object> list = EasyExcel.read("/Users/zhuangjiaju/Downloads/olay的副本.xlsx").sheet(0).doReadSync(); List<Object> list = EasyExcel.read("/Users/zhuangjiaju/Downloads/olay (1).xlsx").sheet(0).doReadSync();
LOGGER.info("数据:{}", list.size()); LOGGER.info("数据:{}", list.size());
for (Object data : list) { for (Object data : list) {
LOGGER.info("返回数据:{}", CollectionUtils.size(data)); LOGGER.info("返回数据:{}", CollectionUtils.size(data));

31
src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java

@ -12,9 +12,11 @@ import com.alibaba.easyexcel.test.temp.data.HeadType;
import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.Data;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -86,12 +88,15 @@ public class WriteV33Test {
@Test @Test
public void indexWrite() { public void indexWrite() {
String fileName = TestFileUtil.getPath() + "indexWrite" + System.currentTimeMillis() + ".xlsx"; String fileName = TestFileUtil.getPath() + "indexWrite" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(fileName, IndexData.class) Man man = new Man();
.excludeColumnIndexes(Collections.singleton(0)) man.setAddr("武汉");
.sheet("模板") man.setName("张三");
.excludeColumnIndexes(Collections.singleton(1)) ExcelWriter excelWriter = EasyExcel.write(fileName, Humen.class).build();
.doWrite(indexData()); WriteSheet writeSheet = EasyExcel.writerSheet("test").build();
excelWriter.write(Collections.singletonList(man), writeSheet);
// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();
} }
private List<IndexData> indexData() { private List<IndexData> indexData() {
@ -105,4 +110,18 @@ public class WriteV33Test {
} }
return list; return list;
} }
@Data
static class Humen{
@ExcelProperty("名字")
private String name;
}
@Data
static
class Man extends Humen{
@ExcelProperty("地址")
private String addr;
}
} }

Loading…
Cancel
Save