public void formatValue()

in poi/src/main/java/org/apache/poi/ss/format/CellNumberFormatter.java [427:560]


    public void formatValue(StringBuffer toAppendTo, Object valueObject) {
        BigDecimal bd = BigDecimal.valueOf(((Number) valueObject).doubleValue()).multiply(BigDecimal.valueOf(scale));
        double value = bd.doubleValue();

        // For negative numbers:
        // - If the cell format has a negative number format, this method
        // is called with a positive value and the number format has
        // the negative formatting required, e.g. minus sign or brackets.
        // - If the cell format does not have a negative number format,
        // this method is called with a negative value and the number is
        // formatted with a minus sign at the start.
        boolean negative = value < 0;
        if (negative)
            value = -value;

        // Split out the fractional part if we need to print a fraction
        double fractional = 0;
        if (slash != null) {
            if (improperFraction) {
                fractional = value;
                value = 0;
            } else {
                fractional = value % 1.0;
                //noinspection SillyAssignment
                value = (long) value;
            }
        }

        Set<CellNumberStringMod> mods = new TreeSet<>();
        StringBuffer output = new StringBuffer(localiseFormat(desc));

        if (exponent != null) {
            writeScientific(value, output, mods);
        } else if (improperFraction) {
            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 (numerator == null) {
                writeFractional(result, output);
                writeInteger(result, output, integerSpecials, mods, showGroupingSeparator);
            } else {
                writeFraction(value, result, fractional, output, mods);
            }
        }

        DecimalFormatSymbols dfs = getDecimalFormatSymbols();
        String groupingSeparator = Character.toString(dfs.getGroupingSeparator());

        // Now strip out any remaining '#'s and add any pending text ...
        Iterator<CellNumberStringMod> changes = mods.iterator();
        CellNumberStringMod nextChange = (changes.hasNext() ? changes.next() : null);
        // records chars already deleted
        SparseBitSet deletedChars = new SparseBitSet();
        int adjust = 0;
        for (Special s : specials) {
            int adjustedPos = s.pos + adjust;
            if (!deletedChars.get(s.pos) && output.charAt(adjustedPos) == '#') {
                output.deleteCharAt(adjustedPos);
                adjust--;
                deletedChars.set(s.pos);
            }
            while (nextChange != null && s == nextChange.getSpecial()) {
                int lenBefore = output.length();
                int modPos = s.pos + adjust;
                switch (nextChange.getOp()) {
                case CellNumberStringMod.AFTER:
                    // ignore adding a comma after a deleted char (which was a '#')
                    if (nextChange.getToAdd().equals(groupingSeparator) && deletedChars.get(s.pos)) {
                        break;
                    }
                    output.insert(modPos + 1, nextChange.getToAdd());
                    break;
                case CellNumberStringMod.BEFORE:
                    output.insert(modPos, nextChange.getToAdd());
                    break;

                case CellNumberStringMod.REPLACE:
                    // delete starting pos in original coordinates
                    int delPos = s.pos;
                    if (!nextChange.isStartInclusive()) {
                        delPos++;
                        modPos++;
                    }

                    // Skip over anything already deleted
                    while (deletedChars.get(delPos)) {
                        delPos++;
                        modPos++;
                    }

                    // delete end point in original
                    int delEndPos = nextChange.getEnd().pos;
                    if (nextChange.isEndInclusive()) {
                        delEndPos++;
                    }

                    // delete end point in current
                    int modEndPos = delEndPos + adjust;

                    if (modPos < modEndPos) {
                        if (nextChange.getToAdd() != null && nextChange.getToAdd().length() == 0) {
                            output.delete(modPos, modEndPos);
                        }
                        else {
                            char fillCh = nextChange.getToAdd().charAt(0);
                            for (int i = modPos; i < modEndPos; i++) {
                                output.setCharAt(i, fillCh);
                            }
                        }
                        deletedChars.set(delPos, delEndPos);
                    }
                    break;

                default:
                    throw new IllegalStateException("Unknown op: " + nextChange.getOp());
                }
                adjust += output.length() - lenBefore;

                nextChange = (changes.hasNext()) ? changes.next() : null;
            }
        }

        // Finally, add it to the string
        if (negative) {
            toAppendTo.append('-');
        }
        toAppendTo.append(output);
    }