diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v03/handlers/RkRecordHandler.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v03/handlers/RkRecordHandler.java index 1d117e64e..3c5c5370c 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v03/handlers/RkRecordHandler.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v03/handlers/RkRecordHandler.java @@ -25,29 +25,51 @@ package org.apache.fesod.sheet.analysis.v03.handlers; +import java.math.BigDecimal; import org.apache.fesod.sheet.analysis.v03.IgnorableXlsRecordHandler; +import org.apache.fesod.sheet.constant.BuiltinFormats; import org.apache.fesod.sheet.context.xls.XlsReadContext; +import org.apache.fesod.sheet.enums.RowTypeEnum; +import org.apache.fesod.sheet.metadata.data.DataFormatData; import org.apache.fesod.sheet.metadata.data.ReadCellData; import org.apache.poi.hssf.record.RKRecord; import org.apache.poi.hssf.record.Record; /** - * Record handler + * Record handler for BIFF {@link RKRecord}. + * + *
RK is a compact numeric cell used by older Excel files. The event-API path still delivers these + * records; they must be decoded like {@link NumberRecordHandler}, not treated as empty cells. */ public class RkRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override - public void processRecord(XlsReadContext xlsReadContext, Record record) { - RKRecord re = (RKRecord) record; + public void processRecord(XlsReadContext xlsReadContext, Record rec) { + RKRecord re = (RKRecord) rec; Integer targetColumnIndex = xlsReadContext.readSheetHolder().determineTargetColumnIndex(re.getColumn()); if (targetColumnIndex == null) { return; } - xlsReadContext - .xlsReadSheetHolder() - .getCellMap() - .put(targetColumnIndex, ReadCellData.newEmptyInstance(re.getRow(), targetColumnIndex)); + short dataFormat = (short) xlsReadContext + .xlsReadWorkbookHolder() + .getFormatTrackingHSSFListener() + .getFormatIndex(re); + DataFormatData dataFormatData = new DataFormatData(); + dataFormatData.setIndex(dataFormat); + dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat( + dataFormat, + xlsReadContext + .xlsReadWorkbookHolder() + .getFormatTrackingHSSFListener() + .getFormatString(re), + xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale())); + + ReadCellData> cellData = + ReadCellData.newInstanceOriginal(BigDecimal.valueOf(re.getRKNumber()), re.getRow(), targetColumnIndex); + cellData.setDataFormatData(dataFormatData); + xlsReadContext.xlsReadSheetHolder().getCellMap().put(targetColumnIndex, cellData); + xlsReadContext.xlsReadSheetHolder().setTempRowType(RowTypeEnum.DATA); } } diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/analysis/v03/handlers/RkRecordHandlerTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/analysis/v03/handlers/RkRecordHandlerTest.java new file mode 100644 index 000000000..3f8a07144 --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/analysis/v03/handlers/RkRecordHandlerTest.java @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.fesod.sheet.analysis.v03.handlers; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Stream; +import org.apache.fesod.sheet.context.xls.XlsReadContext; +import org.apache.fesod.sheet.enums.CellDataTypeEnum; +import org.apache.fesod.sheet.enums.RowTypeEnum; +import org.apache.fesod.sheet.metadata.Cell; +import org.apache.fesod.sheet.metadata.GlobalConfiguration; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.read.metadata.holder.ReadSheetHolder; +import org.apache.fesod.sheet.read.metadata.holder.xls.XlsReadSheetHolder; +import org.apache.fesod.sheet.read.metadata.holder.xls.XlsReadWorkbookHolder; +import org.apache.fesod.sheet.testkit.Tags; +import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; +import org.apache.poi.hssf.record.RKRecord; +import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.util.LittleEndianOutputStream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mockito; + +/** + * Regression test: BIFF {@link RKRecord} numeric cells must be decoded, not stored as EMPTY. + * + *
Modern Excel / POI usermodel writes {@code NUMBER} records, not {@code RK}. The event-API path
+ * still sees {@code RK} in older BIFF files, so this test builds real {@link RKRecord}s from bytes
+ * covering the RK encodings supported by Apache POI ({@code RKUtil.decodeNumber}).
+ */
+@Tag(Tags.UNIT)
+class RkRecordHandlerTest {
+
+ private static final int ROW = 3;
+ private static final int COLUMN = 1;
+ private static final String FORMAT_STRING = "0.00";
+
+ @Test
+ void processRecord_preservesDataFormatAndMarksRowAsData() throws IOException {
+ Map