From 8c697950a53e97e772b07d5fbfbfb5e66bc1871e Mon Sep 17 00:00:00 2001 From: zhuangjiaju Date: Mon, 19 Aug 2019 16:39:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=BB=E5=86=99=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/excel/ExcelReader.java | 2 +- .../excel/analysis/ExcelAnalyserImpl.java | 16 +- .../excel/analysis/v03/XlsSaxAnalyser.java | 3 + .../v03/handlers/NumberRecordHandler.java | 2 + .../v07/SharedStringsTableHandler.java | 21 ++- .../analysis/v07/XlsxHandlerFactory.java | 8 +- .../excel/analysis/v07/XlsxRowHandler.java | 5 +- .../excel/analysis/v07/XlsxSaxAnalyser.java | 13 +- .../v07/handlers/DefaultCellHandler.java | 26 +++- .../excel/constant/ExcelXmlConstants.java | 4 + .../excel/context/WriteContextImpl.java | 35 +++-- .../string/StringNumberConverter.java | 14 ++ .../com/alibaba/excel/metadata/CellData.java | 26 ++++ .../alibaba/excel/write/ExcelBuilderImpl.java | 4 +- .../core/converter/ConverterDataTest.java | 2 +- .../core/converter/ReadAllConverterData.java | 1 + .../ReadAllConverterDataListener.java | 1 + .../easyexcel/test/temp/StyleTest.java | 138 ++++++++++++++++++ .../test/temp/poi/PoiFormatTest.java | 53 +++++++ src/test/resources/converter/converter03.xls | Bin 20480 -> 20992 bytes src/test/resources/converter/converter07.xlsx | Bin 10692 -> 10693 bytes src/test/resources/simple/simple07.xlsx | Bin 10048 -> 10144 bytes update.md | 1 + 23 files changed, 342 insertions(+), 33 deletions(-) create mode 100644 src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java diff --git a/src/main/java/com/alibaba/excel/ExcelReader.java b/src/main/java/com/alibaba/excel/ExcelReader.java index 07378d22..4fcb3cab 100644 --- a/src/main/java/com/alibaba/excel/ExcelReader.java +++ b/src/main/java/com/alibaba/excel/ExcelReader.java @@ -285,7 +285,7 @@ public class ExcelReader { } try { excelAnalyser.finish(); - } catch (Exception e) { + } catch (Throwable e) { LOGGER.warn("Destroy object failed", e); } } diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index b24a182e..c0818187 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -1,7 +1,5 @@ package com.alibaba.excel.analysis; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,7 +32,7 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { } catch (RuntimeException e) { finish(); throw e; - } catch (Exception e) { + } catch (Throwable e) { finish(); throw new ExcelAnalysisException(e); } @@ -72,7 +70,7 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { } catch (RuntimeException e) { finish(); throw e; - } catch (Exception e) { + } catch (Throwable e) { finish(); throw new ExcelAnalysisException(e); } @@ -88,14 +86,22 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { if (readWorkbookHolder.getReadCache() != null) { readWorkbookHolder.getReadCache().destroy(); } + } catch (Throwable e) { + throw new ExcelAnalysisException("Can not close IO", e); + } + try { if (analysisContext.readWorkbookHolder().getAutoCloseStream() && readWorkbookHolder.getInputStream() != null) { readWorkbookHolder.getInputStream().close(); } + } catch (Throwable e) { + throw new ExcelAnalysisException("Can not close IO", e); + } + try { if (readWorkbookHolder.getTempFile() != null) { FileUtils.delete(readWorkbookHolder.getTempFile()); } - } catch (IOException e) { + } catch (Throwable e) { throw new ExcelAnalysisException("Can not close IO", e); } } diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index 92754360..8df8bfd8 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -14,7 +14,10 @@ import org.apache.poi.hssf.eventusermodel.HSSFListener; import org.apache.poi.hssf.eventusermodel.HSSFRequest; import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener; import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; +import org.apache.poi.hssf.record.ExtendedFormatRecord; import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.StyleRecord; +import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index b18a89e2..23aff5a3 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java @@ -30,6 +30,8 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler { this.row = numrec.getRow(); this.column = numrec.getColumn(); this.cellData = new CellData(numrec.getValue()); + this.cellData.setDataFormat(formatListener.getFormatIndex(numrec)); + this.cellData.setDataFormatString(formatListener.getFormatString(numrec)); } @Override diff --git a/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java index de924c91..9d228d2a 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java @@ -1,5 +1,6 @@ package com.alibaba.excel.analysis.v07; +import org.xml.sax.Attributes; import org.xml.sax.helpers.DefaultHandler; import com.alibaba.excel.cache.ReadCache; @@ -11,22 +12,40 @@ import com.alibaba.excel.cache.ReadCache; */ public class SharedStringsTableHandler extends DefaultHandler { private static final String T_TAG = "t"; + private static final String SI_TAG = "si"; + /** + * The final piece of data + */ private String currentData; + /** + * Current element data + */ + private String currentElementData; + private ReadCache readCache; public SharedStringsTableHandler(ReadCache readCache) { this.readCache = readCache; } + @Override + public void startElement(String uri, String localName, String name, Attributes attributes) { + if (SI_TAG.equals(name)) { + currentData = ""; + } + } + @Override public void endElement(String uri, String localName, String name) { if (T_TAG.equals(name)) { + currentData += currentElementData; + } else if (SI_TAG.equals(name)) { readCache.put(currentData); } } @Override public void characters(char[] ch, int start, int length) { - currentData = new String(ch, start, length); + currentElementData = new String(ch, start, length); } } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java index 7fd1dc14..82f7d2c5 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java @@ -3,6 +3,8 @@ package com.alibaba.excel.analysis.v07; import java.util.ArrayList; import java.util.List; +import org.apache.poi.xssf.model.StylesTable; + import com.alibaba.excel.analysis.v07.handlers.CountRowCellHandler; import com.alibaba.excel.analysis.v07.handlers.DefaultCellHandler; import com.alibaba.excel.analysis.v07.handlers.ProcessResultCellHandler; @@ -10,14 +12,14 @@ import com.alibaba.excel.context.AnalysisContext; /** * Build handler - * + * * @author Dan Zheng */ public class XlsxHandlerFactory { - public static List buildCellHandlers(AnalysisContext analysisContext) { + public static List buildCellHandlers(AnalysisContext analysisContext, StylesTable stylesTable) { List result = new ArrayList(); result.add(new CountRowCellHandler(analysisContext)); - DefaultCellHandler defaultCellHandler = new DefaultCellHandler(analysisContext); + DefaultCellHandler defaultCellHandler = new DefaultCellHandler(analysisContext, stylesTable); result.add(defaultCellHandler); result.add(new ProcessResultCellHandler(analysisContext, defaultCellHandler)); return result; diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java index 1a1bbeee..8306fc15 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java @@ -2,6 +2,7 @@ package com.alibaba.excel.analysis.v07; import java.util.List; +import org.apache.poi.xssf.model.StylesTable; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; @@ -17,8 +18,8 @@ public class XlsxRowHandler extends DefaultHandler { private List cellHandlers; private XlsxRowResultHolder rowResultHolder; - public XlsxRowHandler(AnalysisContext analysisContext) { - this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext); + public XlsxRowHandler(AnalysisContext analysisContext, StylesTable stylesTable) { + this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, stylesTable); for (XlsxCellHandler cellHandler : cellHandlers) { if (cellHandler instanceof XlsxRowResultHolder) { this.rowResultHolder = (XlsxRowResultHolder)cellHandler; diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index d7aaea9e..bda0e763 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -15,6 +15,7 @@ import javax.xml.parsers.SAXParserFactory; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.xssf.eventusermodel.XSSFReader; +import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.usermodel.XSSFRelation; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; @@ -47,6 +48,10 @@ public class XlsxSaxAnalyser implements ExcelExecutor { private AnalysisContext analysisContext; private List sheetList; private Map sheetMap; + /** + * Current style information + */ + private StylesTable stylesTable; public XlsxSaxAnalyser(AnalysisContext analysisContext) throws Exception { this.analysisContext = analysisContext; @@ -64,9 +69,9 @@ public class XlsxSaxAnalyser implements ExcelExecutor { analysisSharedStringsTable(sharedStringsTablePackagePart.getInputStream(), readWorkbookHolder); XSSFReader xssfReader = new XSSFReader(pkg); - analysisUse1904WindowDate(xssfReader, readWorkbookHolder); + stylesTable = xssfReader.getStylesTable(); sheetList = new ArrayList(); sheetMap = new HashMap(); XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); @@ -94,12 +99,12 @@ public class XlsxSaxAnalyser implements ExcelExecutor { } if (size < USE_MAP_CACHE_SIZE) { if (LOGGER.isDebugEnabled()) { - LOGGER.info("Use map cache.size:{}", size); + LOGGER.debug("Use map cache.size:{}", size); } readWorkbookHolder.setReadCache(new MapCache()); } else { if (LOGGER.isDebugEnabled()) { - LOGGER.info("Use ehcache.size:{}", size); + LOGGER.debug("Use ehcache.size:{}", size); } readWorkbookHolder.setReadCache(new Ehcache()); } @@ -178,7 +183,7 @@ public class XlsxSaxAnalyser implements ExcelExecutor { @Override public void execute() { parseXmlSource(sheetMap.get(analysisContext.readSheetHolder().getSheetNo()), - new XlsxRowHandler(analysisContext)); + new XlsxRowHandler(analysisContext, stylesTable)); } } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java index ba890bd4..671693b4 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java @@ -1,5 +1,6 @@ package com.alibaba.excel.analysis.v07.handlers; +import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_DATA_FORMAT_TAG; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_FORMULA_TAG; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_TAG; @@ -9,6 +10,9 @@ import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG; import java.util.Map; import java.util.TreeMap; +import org.apache.poi.ss.usermodel.BuiltinFormats; +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; @@ -36,9 +40,14 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder private int curCol; private Map curRowContent = new TreeMap(); private CellData currentCellData; + /** + * Current style information + */ + private StylesTable stylesTable; - public DefaultCellHandler(AnalysisContext analysisContext) { + public DefaultCellHandler(AnalysisContext analysisContext, StylesTable stylesTable) { this.analysisContext = analysisContext; + this.stylesTable = stylesTable; } @Override @@ -75,6 +84,21 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder // t is null ,it's means Empty or Number CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(CELL_VALUE_TYPE_TAG)); currentCellData = new CellData(type); + + // Put in data transformation information + String dateFormatIndex = attributes.getValue(CELL_DATA_FORMAT_TAG); + if (dateFormatIndex != null) { + int dateFormatIndexInteger = Integer.parseInt(dateFormatIndex); + XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); + int dataFormat = xssfCellStyle.getDataFormat(); + String dataFormatString = xssfCellStyle.getDataFormatString(); + currentCellData.setDataFormat(dataFormat); + if (dataFormatString == null) { + currentCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat)); + } else { + currentCellData.setDataFormatString(dataFormatString); + } + } } // cell is formula if (CELL_FORMULA_TAG.equals(name)) { diff --git a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index 55d522fa..f01a33b3 100644 --- a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -11,6 +11,10 @@ public class ExcelXmlConstants { public static final String ROW_TAG = "row"; public static final String CELL_TAG = "c"; public static final String CELL_VALUE_TYPE_TAG = "t"; + /** + * Number formatted label + */ + public static final String CELL_DATA_FORMAT_TAG = "s"; public static final String CELL_FORMULA_TAG = "f"; public static final String CELL_VALUE_TAG = "v"; /** diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index ff2215e0..ebe0d269 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -1,6 +1,5 @@ package com.alibaba.excel.context; -import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.Map; @@ -347,19 +346,29 @@ public class WriteContextImpl implements WriteContext { try { writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream()); writeWorkbookHolder.getWorkbook().close(); - if (writeWorkbookHolder.getAutoCloseStream()) { - if (writeWorkbookHolder.getOutputStream() != null) { - writeWorkbookHolder.getOutputStream().close(); - } - if (writeWorkbookHolder.getTemplateInputStream() != null) { - writeWorkbookHolder.getTemplateInputStream().close(); - } - } else { - if (writeWorkbookHolder.getFile() != null && writeWorkbookHolder.getOutputStream() != null) { - writeWorkbookHolder.getOutputStream().close(); - } + } catch (Throwable e) { + throw new ExcelGenerateException("Can not close IO", e); + } + try { + if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getOutputStream() != null) { + writeWorkbookHolder.getOutputStream().close(); + } + } catch (Throwable e) { + throw new ExcelGenerateException("Can not close IO", e); + } + try { + if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getTemplateInputStream() != null) { + writeWorkbookHolder.getTemplateInputStream().close(); + } + } catch (Throwable e) { + throw new ExcelGenerateException("Can not close IO", e); + } + try { + if (!writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getFile() != null + && writeWorkbookHolder.getOutputStream() != null) { + writeWorkbookHolder.getOutputStream().close(); } - } catch (IOException e) { + } catch (Throwable e) { throw new ExcelGenerateException("Can not close IO", e); } if (LOGGER.isDebugEnabled()) { diff --git a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java index 934135e2..62b25238 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java @@ -1,6 +1,7 @@ package com.alibaba.excel.converters.string; import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.DateUtil; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; @@ -38,6 +39,19 @@ public class StringNumberConverter implements Converter { contentProperty.getDateTimeFormatProperty().getFormat()); } // If there are "NumberFormat", read as number + if (contentProperty != null && contentProperty.getNumberFormatProperty() != null) { + return NumberUtils.format(cellData.getDoubleValue(), contentProperty); + } + // Excel defines formatting + if (cellData.getDataFormat() != null) { + if (DateUtil.isADateFormat(cellData.getDataFormat(), cellData.getDataFormatString())) { + return DateUtils.format(HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), + globalConfiguration.getUse1904windowing(), null)); + } else { + return NumberUtils.format(cellData.getDoubleValue(), contentProperty); + } + } + // Default conversion number return NumberUtils.format(cellData.getDoubleValue(), contentProperty); } diff --git a/src/main/java/com/alibaba/excel/metadata/CellData.java b/src/main/java/com/alibaba/excel/metadata/CellData.java index 03fee7a7..e03a883b 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellData.java +++ b/src/main/java/com/alibaba/excel/metadata/CellData.java @@ -23,6 +23,14 @@ public class CellData { private Boolean booleanValue; private Boolean formula; private String formulaValue; + /** + * The number formatting + */ + private Integer dataFormat; + /** + * The string of number formatting + */ + private String dataFormatString; public CellData(CellData other) { this.type = other.type; @@ -31,6 +39,8 @@ public class CellData { this.booleanValue = other.booleanValue; this.formula = other.formula; this.formulaValue = other.formulaValue; + this.dataFormat = other.dataFormat; + this.dataFormatString = other.dataFormatString; } public CellData(String stringValue) { @@ -123,6 +133,22 @@ public class CellData { this.formulaValue = formulaValue; } + public Integer getDataFormat() { + return dataFormat; + } + + public void setDataFormat(Integer dataFormat) { + this.dataFormat = dataFormat; + } + + public String getDataFormatString() { + return dataFormatString; + } + + public void setDataFormatString(String dataFormatString) { + this.dataFormatString = dataFormatString; + } + @Override public String toString() { switch (type) { diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index 25dee195..970fd3cb 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -51,7 +51,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { } catch (RuntimeException e) { finish(); throw e; - } catch (Exception e) { + } catch (Throwable e) { finish(); throw new ExcelGenerateException(e); } @@ -88,7 +88,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { } catch (RuntimeException e) { finish(); throw e; - } catch (Exception e) { + } catch (Throwable e) { finish(); throw new ExcelGenerateException(e); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java index 5e6978e0..85f5f39b 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java @@ -53,7 +53,7 @@ public class ConverterDataTest { } @Test - public void T03ReadAllConverter03() { + public void T04ReadAllConverter03() { readAllConverter("converter" + File.separator + "converter03.xls"); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterData.java b/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterData.java index 6ff280ec..4f758a02 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterData.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterData.java @@ -42,4 +42,5 @@ public class ReadAllConverterData { private String stringError; private String stringFormulaNumber; private String stringFormulaString; + private String stringNumberDate; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java index d756a69b..f4f0a1e7 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java @@ -64,6 +64,7 @@ public class ReadAllConverterDataListener extends AnalysisEventListener list = EasyExcel.read("D:\\test\\styleTest.xls").sheet().headRowNumber(0).doReadSync(); + for (Object data : list) { + LOGGER.info("返回数据:{}", JSON.toJSONString(data)); + } + } + + @Test + public void poi() throws Exception { + InputStream is = new FileInputStream("D:\\test\\styleTest.xls"); + HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is); + HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0); + HSSFRow hssfRow = hssfSheet.getRow(0); + System.out.println(hssfRow.getCell(0).getCellStyle().getDataFormatString()); + DataFormatter formatter = new DataFormatter(); + System.out.println(hssfRow.getCell(0).getNumericCellValue()); + System.out.println(hssfRow.getCell(1).getNumericCellValue()); + System.out.println(hssfRow.getCell(2).getNumericCellValue()); + System.out.println(hssfRow.getCell(0).getCellStyle().getDataFormatString()); + System.out.println(hssfRow.getCell(1).getCellStyle().getDataFormatString()); + System.out.println(hssfRow.getCell(2).getCellStyle().getDataFormatString()); + + } + + @Test + public void poi07() throws Exception { + InputStream is = new FileInputStream("D:\\test\\styleTest.xlsx"); + Workbook workbook = WorkbookFactory.create(is); // 这种方式 Excel 2003/2007/2010 都是可以处理的 + Sheet sheet = workbook.getSheetAt(0); + Row hssfRow = sheet.getRow(0); + System.out.println(hssfRow.getCell(0).getCellStyle().getDataFormatString()); + DataFormatter formatter = new DataFormatter(); + System.out.println(hssfRow.getCell(0).getNumericCellValue()); + System.out.println(hssfRow.getCell(1).getNumericCellValue()); + System.out.println(hssfRow.getCell(2).getNumericCellValue()); + System.out.println(hssfRow.getCell(0).getCellStyle().getDataFormat()); + System.out.println(hssfRow.getCell(1).getCellStyle().getDataFormat()); + System.out.println(hssfRow.getCell(2).getCellStyle().getDataFormat()); + System.out.println(hssfRow.getCell(3).getCellStyle().getDataFormat()); + System.out.println(hssfRow.getCell(0).getCellStyle().getDataFormatString()); + System.out.println(hssfRow.getCell(1).getCellStyle().getDataFormatString()); + System.out.println(hssfRow.getCell(2).getCellStyle().getDataFormatString()); + System.out.println(hssfRow.getCell(3).getCellStyle().getDataFormatString()); + isDate(hssfRow.getCell(0)); + isDate(hssfRow.getCell(1)); + isDate(hssfRow.getCell(2)); + isDate(hssfRow.getCell(3)); + + } + + @Test + public void poi0701() throws Exception { + InputStream is = new FileInputStream("D:\\test\\f1.xlsx"); + Workbook workbook = WorkbookFactory.create(is); // 这种方式 Excel 2003/2007/2010 都是可以处理的 + Sheet sheet = workbook.getSheetAt(0); + print(sheet.getRow(0).getCell(0)); + print(sheet.getRow(1).getCell(0)); + print(sheet.getRow(2).getCell(0)); + print(sheet.getRow(3).getCell(0)); + } + + private void print(Cell cell) { + System.out.println( + DateUtil.isADateFormat(cell.getCellStyle().getDataFormat(), cell.getCellStyle().getDataFormatString())); + System.out.println(cell.getCellStyle().getDataFormat()); + System.out.println(cell.getCellStyle().getDataFormatString()); + DataFormatter f = new DataFormatter(); + System.out.println(f.formatCellValue(cell)); + if (cell.getCellStyle().getDataFormatString() != null) { + + } + ExcelStyleDateFormatter ff = new ExcelStyleDateFormatter(cell.getCellStyle().getDataFormatString()); + + } + + @Test + public void testFormatter() throws Exception { + ExcelStyleDateFormatter ff = new ExcelStyleDateFormatter("yyyy年m月d日"); + + System.out.println(ff.format(new Date())); + } + + private void isDate(Cell cell) { + System.out.println( + DateUtil.isADateFormat(cell.getCellStyle().getDataFormat(), cell.getCellStyle().getDataFormatString())); + System.out.println(HSSFDateUtil.isCellDateFormatted(cell)); + DataFormatter f = new DataFormatter(); + System.out.println(f.formatCellValue(cell)); + + } + + @Test + public void testBuiltinFormats() throws Exception { + System.out.println(BuiltinFormats.getBuiltinFormat(48)); + System.out.println(BuiltinFormats.getBuiltinFormat(57)); + System.out.println(BuiltinFormats.getBuiltinFormat(28)); + + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java new file mode 100644 index 00000000..99885fa9 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java @@ -0,0 +1,53 @@ +package com.alibaba.easyexcel.test.temp.poi; + +import java.io.File; +import java.io.IOException; + +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.easyexcel.test.util.TestFileUtil; + +/** + * 测试poi + * + * @author Jiaju Zhuang + **/ +@Ignore +public class PoiFormatTest { + private static final Logger LOGGER = LoggerFactory.getLogger(PoiFormatTest.class); + + @Test + public void lastRowNum() throws IOException { + String file = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + SXSSFWorkbook xssfWorkbook = new SXSSFWorkbook(new XSSFWorkbook(file)); + SXSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0); + LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); + SXSSFRow row = xssfSheet.getRow(0); + LOGGER.info("第一行数据:{}", row); + xssfSheet.createRow(20); + LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); + } + + @Test + public void lastRowNumXSSF() throws IOException { + String file = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file); + LOGGER.info("一共:{}个sheet", xssfWorkbook.getNumberOfSheets()); + XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0); + LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); + XSSFRow row = xssfSheet.getRow(0); + LOGGER.info("第一行数据:{}", row); + xssfSheet.createRow(20); + LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); + } +} diff --git a/src/test/resources/converter/converter03.xls b/src/test/resources/converter/converter03.xls index 6ae32b9a24c20306a248bcc00380caadbb9ae717..3373d81ee35119586d3f2bd033893082c0f67776 100644 GIT binary patch delta 948 zcma)5T}V_>5T3dFcU|?~-RtV=;?G@OSHfUz1u=7VcNLXw(LhLO$rStvin0(xBsAy; z63TX70}Fzl3gVJMJtQIYAY?`=M4&;6M>>OP>)G66Tj$1xj;~;V*?AhbPT~svV2sna zZ33Ofo~;%e0Wy;_$X~$qh=kLr?yf`N5$1pJbXN|NPc9_Q;h|Nzm@YaBDa`geM?qTl zQG(UyOxMHC4Q@d`Wn5l#(o4mQDuvwp5hLy)k(+ZYE8etLXBO(vN=@>hAZcdb zqIoT>h(ux_aDfqet9fyhwzXn=EA*~?)(mH!RiPTM#&@!-mzr9Ov8z8Sk`C0 zGa|z6*bS#)kmo3b;Tk7B*-T3f7aT28HM=W~_9Hu(Cj<7Rf)nA+t79XBJ*myXvSA8G zS}m3Ek;Wsn(saal%y-;;8FE1935p65SOFwO6k%NqKZ`8!c1>L|e+@v@fj)|(bF z`xiLb&>;>wJ&abNpOzTQ>6@vS#mcaPnqz_=Hu1KJ&rDo5(Gjo00EOZ=+AX{R{@Y4Q79TdPsh;g;M#`#0DLz^lj&PP&qe yQ8aPi_Oy>*6m2Cwq?4m|(X{~5ax!5oBpZ=xtX5h$+L-PR@%VnRYtl49bA zNP^gFTq+t@E+jaH1u@!%iKq)*Xo#$2VPbS4AwuFp>z#@2jPK=~xu0|IdpGl@@8k3W z&Ua$nQr8Q_1`>sw|5veCG!X`XMuz1t4W7ij{d5`3#a~XP-(x)|rfJfiL!ckbF`5)F zpv%}6TXByL#oRoy0RD#X9~#{jI?!LC_)k-mA; ztZ7%H|Ijr5(d1OK&!XBxb>*rf1vBaFTVrpz-D51&Uat@?wNpz+Af$BhA>hCvI0Ywo zk3$SD^POh8>1f9}=Wd~i(_!O7$5*7au3lRhGF08&DlB(WN$(cziz`tOJZ29NEY_JN zfrsR!gU9;IfU*@c9o@JYe~ok|8AhG*$q3fcN-|QbbIQhz5L}Ri@J`k6#^|TSPjGX@ z4GE|tAr;|@CW{YSeBR=F7QbSyr>)f0wl$F8yA61T0(J{3EIar@+yUS?!(3G$gG~lM zo5&_xexuOix8?Wi4d!EZbE1S%$}oL%Jegq*NlX$ B)%5@X diff --git a/src/test/resources/converter/converter07.xlsx b/src/test/resources/converter/converter07.xlsx index a210bbc2fd942981c41d71f992460a37946ab690..92b93e20f4b822c9f121af369693f166c5b5305f 100644 GIT binary patch delta 4980 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 delta 5051 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 diff --git a/src/test/resources/simple/simple07.xlsx b/src/test/resources/simple/simple07.xlsx index f01c4460b032536ed1a21a8dc9c3f30964c3afcd..3d25fcd8c7bb009e5347b61119a23e145148d0ff 100644 GIT binary patch delta 4435 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 delta 4309 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