diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 22a9ec10e2..f049a1023f 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -3938,6 +3938,20 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { } } + @Test + void testBug69812() throws Exception { + try (XSSFWorkbook wb = openSampleWorkbook("bug69812.xlsx")) { + XSSFSheet sheet = wb.getSheetAt(0); + XSSFRow row = sheet.getRow(0); + XSSFCell cellA1 = row.getCell(0); + DataFormatter dataFormatter = new DataFormatter(); + String cellValue = dataFormatter.formatCellValue(cellA1); + // https://bz.apache.org/bugzilla/show_bug.cgi?id=69812: user says this should be "25,386" + assertEquals("25,396", cellValue); + assertEquals("#,##0,,", cellA1.getCellStyle().getDataFormatString()); + } + } + private static void readByCommonsCompress(File temp_excel_poi) throws IOException { /* read by commons-compress*/ try (ZipFile zipFile = ZipFile.builder().setFile(temp_excel_poi).get()) { diff --git a/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java b/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java index bfe795025e..e0ceb03a7b 100644 --- a/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -808,6 +808,10 @@ public class DataFormatter { } } + boolean requiresScaling() { + return divider != null; + } + private Object scaleInput(Object obj) { if (divider != null) { if (obj instanceof BigDecimal) { @@ -965,12 +969,22 @@ public class DataFormatter { if (numberFormat == null) { return Double.toString(d); } - String formatted; - try { - //see https://github.com/apache/poi/pull/321 -- but this sometimes fails, thus the catch and retry - formatted = numberFormat.format(BigDecimal.valueOf(d)); - } catch (NumberFormatException nfe) { - formatted = numberFormat.format(d); + String formatted = null; + if (numberFormat instanceof InternalDecimalFormatWithScale) { + InternalDecimalFormatWithScale idfws = (InternalDecimalFormatWithScale) numberFormat; + if (idfws.requiresScaling()) { + // hack for https://bz.apache.org/bugzilla/show_bug.cgi?id=69812 + // the https://github.com/apache/poi/pull/321 hack causes problems here + formatted = idfws.format(d); + } + } + if (formatted == null) { + try { + //see https://github.com/apache/poi/pull/321 -- but this sometimes fails, thus the catch and retry + formatted = numberFormat.format(BigDecimal.valueOf(d)); + } catch (NumberFormatException nfe) { + formatted = numberFormat.format(d); + } } return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation } diff --git a/test-data/spreadsheet/bug69812.xlsx b/test-data/spreadsheet/bug69812.xlsx new file mode 100644 index 0000000000..01dd98ed3c Binary files /dev/null and b/test-data/spreadsheet/bug69812.xlsx differ