diff --git a/poi/src/main/java/org/apache/poi/ss/format/CellNumberFormatter.java b/poi/src/main/java/org/apache/poi/ss/format/CellNumberFormatter.java index 11b08e927f4..8a0e2e0b531 100644 --- a/poi/src/main/java/org/apache/poi/ss/format/CellNumberFormatter.java +++ b/poi/src/main/java/org/apache/poi/ss/format/CellNumberFormatter.java @@ -461,10 +461,22 @@ public void formatValue(StringBuffer toAppendTo, Object valueObject) { writeFraction(value, null, fractional, output, mods); } else { StringBuffer result = new StringBuffer(); - try (Formatter f = new Formatter(result, locale)) { - f.format(locale, printfFmt, value); - } catch (IllegalFormatException e) { - throw new IllegalArgumentException("Format: " + printfFmt, e); + + if (value == 0.0 && decimalPoint == null && !desc.contains("0") + && specials.size() == calculateIntegerPartWidth()) { + // Excel's # with value 0 should output empty, not 0 as in Java. + // Excel's ? with value 0 should output space, not 0 as in Java. + for (Special s : specials) { + if (s.ch == '?') { + result.append(' '); + } + } + } else { + try (Formatter f = new Formatter(result, locale)) { + f.format(locale, printfFmt, value); + } catch (IllegalFormatException e) { + throw new IllegalArgumentException("Format: " + printfFmt, e); + } } if (numerator == null) { diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java b/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java index b1fced30a54..49ef8bf6261 100644 --- a/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java +++ b/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java @@ -616,13 +616,15 @@ void testFormatsWithPadding() { assertEquals(" 0.10 ", dfUS.formatRawCellContents( 0.1, -1, "_-* #,##0.00_-;-* #,##0.00_-;_-* \"-\"??_-;_-@_-")); assertEquals("- 0.10 ", dfUS.formatRawCellContents(-0.1, -1, "_-* #,##0.00_-;-* #,##0.00_-;_-* \"-\"??_-;_-@_-")); - // TODO Fix this, we are randomly adding a 0 at the end that shouldn't be there - //assertEquals(" - ", dfUS.formatRawCellContents(0.0, -1, "_-* #,##0.00_-;-* #,##0.00_-;_-* \"-\"??_-;_-@_-")); + // Repeating fill character `* ` doesn't really fill because we do not know the cell's width. + // We just repeat it 3 times. + assertEquals(" - ", dfUS.formatRawCellContents(0.0, -1, "_-* #,##0.00_-;-* #,##0.00_-;_-* \"-\"??_-;_-@_-")); assertEquals(" $ 1.10 ", dfUS.formatRawCellContents( 1.1, -1, "_-$* #,##0.00_-;-$* #,##0.00_-;_-$* \"-\"??_-;_-@_-")); assertEquals("-$ 1.10 ", dfUS.formatRawCellContents(-1.1, -1, "_-$* #,##0.00_-;-$* #,##0.00_-;_-$* \"-\"??_-;_-@_-")); - // TODO Fix this, we are randomly adding a 0 at the end that shouldn't be there - //assertEquals(" $ - ", dfUS.formatRawCellContents( 0.0, -1, "_-$* #,##0.00_-;-$* #,##0.00_-;_-$* \"-\"??_-;_-@_-")); + // Repeating fill character `* ` doesn't really fill because we do not know the cell's width. + // We just repeat it 3 times. + assertEquals(" $ - ", dfUS.formatRawCellContents( 0.0, -1, "_-$* #,##0.00_-;-$* #,##0.00_-;_-$* \"-\"??_-;_-@_-")); } @Test