From fa8650fbe311b2cd2d2a44d80cb8ec6768245e60 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 12 Jul 2023 22:26:41 +0000 Subject: [PATCH] [bug-66682] fix xslb reading support for formula cells of boolean type. This closes #485 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1910951 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/binary/XSSFBSheetHandler.java | 1 + .../poi/xssf/binary/TestXSSFBSheetParser.java | 147 ++++++++++++++++++ test-data/spreadsheet/bug66682.xlsb | Bin 0 -> 9580 bytes 3 files changed, 148 insertions(+) create mode 100644 poi-ooxml/src/test/java/org/apache/poi/xssf/binary/TestXSSFBSheetParser.java create mode 100644 test-data/spreadsheet/bug66682.xlsb diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/binary/XSSFBSheetHandler.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/binary/XSSFBSheetHandler.java index e84145ed27..7a24234046 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/binary/XSSFBSheetHandler.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/binary/XSSFBSheetHandler.java @@ -98,6 +98,7 @@ public class XSSFBSheetHandler extends XSSFBParser { handleCellReal(data); break; case BrtCellBool: + case BrtFmlaBool: handleBoolean(data); break; case BrtCellError: diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/binary/TestXSSFBSheetParser.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/binary/TestXSSFBSheetParser.java new file mode 100644 index 0000000000..d570c6c8de --- /dev/null +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/binary/TestXSSFBSheetParser.java @@ -0,0 +1,147 @@ +/* ==================================================================== + 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.poi.xssf.binary; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.InputStream; +import java.util.Map; +import java.util.LinkedHashMap; + +import org.apache.poi.POIDataSamples; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.ss.util.CellAddress; +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xssf.eventusermodel.XSSFBReader; +import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; +import org.apache.poi.xssf.usermodel.XSSFComment; +import org.junit.jupiter.api.Test; + +class TestXSSFBSheetParser { + private static POIDataSamples _ssTests = POIDataSamples.getSpreadSheetInstance(); + + /* + * Test reading from a binary spreadsheet that various data types are + * read and that they have the same values as a literal as they + * do as a formula. Reference bug #66682 + */ + @Test + void test66682() throws Exception { + try (OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("bug66682.xlsb"))) { + XSSFBReader reader = new XSSFBReader(pkg); + XSSFBReader.SheetIterator it = (XSSFBReader.SheetIterator) reader.getSheetsData(); + + while (it.hasNext()) { + try (InputStream is = it.next()) { + String name = it.getSheetName(); + if (!"test2".equals(name)) + continue; + ValueGrabber contentHandler = new ValueGrabber(); + contentHandler.startSheet(name); + XSSFBSheetHandler sheetHandler = + new XSSFBSheetHandler(is, + reader.getXSSFBStylesTable(), + it.getXSSFBSheetComments(), + new XSSFBSharedStringsTable(pkg), + contentHandler, + new DataFormatter(), + false); + sheetHandler.parse(); + contentHandler.endSheet(); + + /* + * Check each row grabbed from the spreadsheet and + * assert that the second and third columns are not null, + * not empty and have the same formatted value. + * + * The second column contains the literal value, + * the third column contains the formula + */ + for (Map.Entry me : contentHandler.getRowValues().entrySet()) { + String[] vals = me.getValue(); + assertNotNull(vals[1]); + assertNotNull(vals[2]); + assertFalse(vals[1].trim().isEmpty()); + assertEquals(vals[1], vals[2]); + } + } + } + } + } + + + private static class ValueGrabber + implements XSSFSheetXMLHandler.SheetContentsHandler { + + private int currentRow, currentCol; + private boolean firstRow; + private int maxColumn; + private Map rowValues; + + ValueGrabber() { + maxColumn = -1; + rowValues = new LinkedHashMap<>(); + } + + Map getRowValues() { + return rowValues; + } + + public void startSheet(String sheetName) { + currentRow = -1; + firstRow = true; + } + + @Override + public void endSheet() { + } + + @Override + public void startRow(int rowNum) { + currentRow = rowNum; + currentCol = -1; + } + + @Override + public void endRow(int rowNum) { + if (firstRow) + firstRow = false; + } + + @Override + public void cell(String cellReference, String formattedValue, XSSFComment comment) { + if (cellReference == null) + cellReference = new CellAddress(currentRow, currentCol+1).formatAsString(); + + int thisCol = (new CellReference(cellReference)).getCol(); + if (firstRow) + maxColumn = thisCol > maxColumn ? thisCol : maxColumn; + else if (thisCol > maxColumn) + return; + + + if (!firstRow && formattedValue != null) + rowValues.computeIfAbsent(currentRow, k -> new String[maxColumn+1])[thisCol] = formattedValue; + + currentCol = thisCol; + } + } +} diff --git a/test-data/spreadsheet/bug66682.xlsb b/test-data/spreadsheet/bug66682.xlsb new file mode 100644 index 0000000000000000000000000000000000000000..16cefb6a2034fc26abaa244e87160e683cb2ee8d GIT binary patch literal 9580 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 YR8*FO`%Z{4A#6Yla{Pxw^$qNQ0EXMeD*ylh literal 0 HcmV?d00001