From 43056698d95b8c86794fe99af963ff15720bf94a Mon Sep 17 00:00:00 2001 From: DeleiGuo Date: Wed, 17 Sep 2025 23:57:17 +0800 Subject: [PATCH 1/4] feat: support shared formula in xlsx --- .../v07/handlers/CellFormulaTagHandler.java | 37 +++++++++++++++++-- .../excel/constant/ExcelXmlConstants.java | 10 +++++ .../holder/xlsx/XlsxReadSheetHolder.java | 12 ++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java b/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java index 3427cb2d8..aab3379e1 100644 --- a/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java +++ b/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java @@ -1,13 +1,14 @@ package cn.idev.excel.analysis.v07.handlers; +import cn.idev.excel.constant.ExcelXmlConstants; import cn.idev.excel.context.xlsx.XlsxReadContext; import cn.idev.excel.metadata.data.FormulaData; import cn.idev.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; +import cn.idev.excel.util.StringUtils; import org.xml.sax.Attributes; /** - * Cell Handler - * + * Cell formula tag handler */ public class CellFormulaTagHandler extends AbstractXlsxTagHandler { @@ -15,13 +16,43 @@ public class CellFormulaTagHandler extends AbstractXlsxTagHandler { public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); xlsxReadSheetHolder.setTempFormula(new StringBuilder()); + xlsxReadSheetHolder.setTempSharedIndex(null); + + // shared formula + String t = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_T); + if (StringUtils.isBlank(t) || !ExcelXmlConstants.ATTRIBUTE_SHARED.equals(t)) { + return; + } + String si = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_SHARED_INDEX); + if (StringUtils.isBlank(si)) { + return; + } + xlsxReadSheetHolder.setTempSharedIndex(si); + + String ref = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF); + if (StringUtils.isBlank(ref)) { + return; + } + xlsxReadSheetHolder + .getSharedFormula() + .put(si, xlsxReadSheetHolder.getTempFormula().toString()); } @Override public void endElement(XlsxReadContext xlsxReadContext, String name) { XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); + + String formulaValue = xlsxReadSheetHolder.getTempFormula().toString(); + String sharedIndex = xlsxReadSheetHolder.getTempSharedIndex(); + if (StringUtils.isNotBlank(sharedIndex)) { + if (StringUtils.isBlank(formulaValue)) { + formulaValue = xlsxReadSheetHolder.getSharedFormula().get(sharedIndex); + } + xlsxReadSheetHolder.getSharedFormula().put(sharedIndex, formulaValue); + } + FormulaData formulaData = new FormulaData(); - formulaData.setFormulaValue(xlsxReadSheetHolder.getTempFormula().toString()); + formulaData.setFormulaValue(formulaValue); xlsxReadSheetHolder.getTempCellData().setFormulaData(formulaData); } diff --git a/fastexcel/src/main/java/cn/idev/excel/constant/ExcelXmlConstants.java b/fastexcel/src/main/java/cn/idev/excel/constant/ExcelXmlConstants.java index 767636ba2..7aa18e427 100644 --- a/fastexcel/src/main/java/cn/idev/excel/constant/ExcelXmlConstants.java +++ b/fastexcel/src/main/java/cn/idev/excel/constant/ExcelXmlConstants.java @@ -68,6 +68,16 @@ public class ExcelXmlConstants { */ public static final String ATTRIBUTE_RID = "r:id"; + /** + * shared attribute + */ + public static final String ATTRIBUTE_SHARED = "shared"; + + /** + * shared attribute index + */ + public static final String ATTRIBUTE_SHARED_INDEX = "si"; + /** * Cell range split */ diff --git a/fastexcel/src/main/java/cn/idev/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java b/fastexcel/src/main/java/cn/idev/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java index 38db450d1..1f0611367 100644 --- a/fastexcel/src/main/java/cn/idev/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java +++ b/fastexcel/src/main/java/cn/idev/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java @@ -5,6 +5,8 @@ import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder; import java.util.Deque; import java.util.LinkedList; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -35,6 +37,15 @@ public class XlsxReadSheetHolder extends ReadSheetHolder { * Formula for current label. */ private StringBuilder tempFormula; + /** + * Shared index for current label. + */ + private String tempSharedIndex; + /** + * Shared formula for current sheet. + */ + private Map sharedFormula; + /** * excel Relationship */ @@ -43,6 +54,7 @@ public class XlsxReadSheetHolder extends ReadSheetHolder { public XlsxReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder); this.tagDeque = new LinkedList(); + this.sharedFormula = new ConcurrentHashMap<>(); packageRelationshipCollection = ((XlsxReadWorkbookHolder) readWorkbookHolder) .getPackageRelationshipCollectionMap() .get(readSheet.getSheetNo()); From 033cc8734699324fdf5a02424a6a595511211ca9 Mon Sep 17 00:00:00 2001 From: DeleiGuo Date: Thu, 18 Sep 2025 20:18:25 +0800 Subject: [PATCH 2/4] test: add test case for reading Excel formula --- .../idev/excel/celldata/CellDataDataTest.java | 40 ++++++++++++++---- .../idev/excel/celldata/CellDataReadData.java | 3 -- .../resources/celldata/celldata_formula.xlsx | Bin 0 -> 11181 bytes 3 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 fastexcel/src/test/resources/celldata/celldata_formula.xlsx diff --git a/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java b/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java index 6e7da8d40..347df1a8d 100644 --- a/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java +++ b/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java @@ -1,35 +1,40 @@ package cn.idev.excel.celldata; import cn.idev.excel.FastExcel; +import cn.idev.excel.context.AnalysisContext; import cn.idev.excel.enums.CellDataTypeEnum; +import cn.idev.excel.event.AnalysisEventListener; import cn.idev.excel.metadata.data.FormulaData; import cn.idev.excel.metadata.data.WriteCellData; import cn.idev.excel.util.DateUtils; import cn.idev.excel.util.TestFileUtil; -import java.io.File; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; -/** - * - */ +import java.io.File; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + @TestMethodOrder(MethodOrderer.MethodName.class) +@Slf4j public class CellDataDataTest { private static File file07; private static File file03; private static File fileCsv; + private static File file07_formula; @BeforeAll public static void init() { file07 = TestFileUtil.createNewFile("cellData07.xlsx"); file03 = TestFileUtil.createNewFile("cellData03.xls"); - fileCsv = TestFileUtil.createNewFile("cellDataCsv.csv"); + fileCsv = TestFileUtil.readFile("cellDataCsv.csv"); + file07_formula = TestFileUtil.readFile("celldata" + File.separator + "celldata_formula.xlsx"); } @Test @@ -47,6 +52,25 @@ public void t03ReadAndWriteCsv() throws Exception { readAndWrite(fileCsv); } + @Test + public void t04ReadFormula07() throws Exception { + FastExcel.read(file07_formula, CellDataReadData.class, new AnalysisEventListener() { + @Override + public void invoke(CellDataReadData data, AnalysisContext context) { + Assertions.assertNotNull( + data.getFormulaValue().getFormulaData().getFormulaValue()); + log.info( + "row formula: {}", + data.getFormulaValue().getFormulaData().getFormulaValue()); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + } + }) + .doReadAll(); + } + private void readAndWrite(File file) throws Exception { FastExcel.write(file, CellDataWriteData.class).sheet().doWrite(data()); FastExcel.read(file, CellDataReadData.class, new CellDataDataListener()) diff --git a/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataReadData.java b/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataReadData.java index 733903794..4b6691269 100644 --- a/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataReadData.java +++ b/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataReadData.java @@ -6,9 +6,6 @@ import lombok.Getter; import lombok.Setter; -/** - * - */ @Getter @Setter @EqualsAndHashCode diff --git a/fastexcel/src/test/resources/celldata/celldata_formula.xlsx b/fastexcel/src/test/resources/celldata/celldata_formula.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d0ce5b1c33e247f8604ff225603a05e5543c1596 GIT binary patch literal 11181 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 Z@ssr;Ckg(#=Kw+md|v0G#Orbb`hTfgfPMe~ literal 0 HcmV?d00001 From 814196745a987e262c8cf72cec9a80690db8aad4 Mon Sep 17 00:00:00 2001 From: DeleiGuo Date: Thu, 18 Sep 2025 21:12:52 +0800 Subject: [PATCH 3/4] test: fix the code formatting --- .../cn/idev/excel/celldata/CellDataDataTest.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java b/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java index 347df1a8d..e812908d0 100644 --- a/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java +++ b/fastexcel/src/test/java/cn/idev/excel/celldata/CellDataDataTest.java @@ -8,6 +8,10 @@ import cn.idev.excel.metadata.data.WriteCellData; import cn.idev.excel.util.DateUtils; import cn.idev.excel.util.TestFileUtil; +import java.io.File; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -15,11 +19,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; -import java.io.File; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; - @TestMethodOrder(MethodOrderer.MethodName.class) @Slf4j public class CellDataDataTest { @@ -65,8 +64,7 @@ public void invoke(CellDataReadData data, AnalysisContext context) { } @Override - public void doAfterAllAnalysed(AnalysisContext context) { - } + public void doAfterAllAnalysed(AnalysisContext context) {} }) .doReadAll(); } From 0d29d82e796ded43837cab7792f3610ca00e6c34 Mon Sep 17 00:00:00 2001 From: DeleiGuo Date: Fri, 19 Sep 2025 00:09:40 +0800 Subject: [PATCH 4/4] refactor: optimize formula processing in --- .../v07/handlers/CellFormulaTagHandler.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java b/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java index aab3379e1..ae1bcae60 100644 --- a/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java +++ b/fastexcel/src/main/java/cn/idev/excel/analysis/v07/handlers/CellFormulaTagHandler.java @@ -28,14 +28,6 @@ public void startElement(XlsxReadContext xlsxReadContext, String name, Attribute return; } xlsxReadSheetHolder.setTempSharedIndex(si); - - String ref = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF); - if (StringUtils.isBlank(ref)) { - return; - } - xlsxReadSheetHolder - .getSharedFormula() - .put(si, xlsxReadSheetHolder.getTempFormula().toString()); } @Override @@ -44,11 +36,13 @@ public void endElement(XlsxReadContext xlsxReadContext, String name) { String formulaValue = xlsxReadSheetHolder.getTempFormula().toString(); String sharedIndex = xlsxReadSheetHolder.getTempSharedIndex(); + if (StringUtils.isNotBlank(sharedIndex)) { - if (StringUtils.isBlank(formulaValue)) { + if (StringUtils.isNotBlank(formulaValue)) { + xlsxReadSheetHolder.getSharedFormula().putIfAbsent(sharedIndex, formulaValue); + } else { formulaValue = xlsxReadSheetHolder.getSharedFormula().get(sharedIndex); } - xlsxReadSheetHolder.getSharedFormula().put(sharedIndex, formulaValue); } FormulaData formulaData = new FormulaData();