package com.vaadin.addon.spreadsheet; /* * #%L * Vaadin Spreadsheet * %% * Copyright (C) 2013 - 2015 Vaadin Ltd * %% * This program is available under Commercial Vaadin Add-On License 3.0 * (CVALv3). * * See the file license.html distributed with this software for more * information about licensing. * * You should have received a copy of the CVALv3 along with this program. * If not, see <http://vaadin.com/license/cval-3>. * #L% */ import java.io.Serializable; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Arrays; /** * Utility class for formatting cell values */ public class CellValueFormatter implements Serializable { private DecimalFormatSymbols localeDecimalSymbols = DecimalFormatSymbols .getInstance(); public String getScientificNotationStringForNumericCell( double numericValue, String formattedValue, float cellWidthRatio, int width) { BigDecimal ratio = new BigDecimal(cellWidthRatio); BigDecimal columnWidth = new BigDecimal(width); int numberOfDigits = columnWidth.divide(ratio, RoundingMode.DOWN) .intValue(); if (numberOfDigits < 2) { return "#"; } else { int integerPartLength = formattedValue.indexOf(localeDecimalSymbols .getDecimalSeparator()); if (integerPartLength == -1) { integerPartLength = formattedValue.length(); } StringBuilder format = new StringBuilder("0"); if (integerPartLength == formattedValue.length() && numberOfDigits <= 4 && integerPartLength > numberOfDigits) { return createFillString(numberOfDigits); } // Needs scientific if integer part doesn't fit or if it's only // decimals and all decimal don't fit boolean needsScientific = integerPartLength > numberOfDigits || (Math.abs(numericValue) < 1 && formattedValue.length() > numberOfDigits && numberOfDigits > 4); int numberOfDecimals = 0; if (needsScientific) { // 0.#E10 numberOfDecimals = numberOfDigits - 5; } else { numberOfDecimals = numberOfDigits - (integerPartLength + 1); } if (numberOfDecimals > 0) { format.append('.'); for (int i = 0; i < numberOfDecimals; i++) { format.append('#'); } } if (needsScientific) { format.append("E0"); } if (format.length() > numberOfDigits) { return createFillString(numberOfDigits); } return new DecimalFormat(format.toString(), localeDecimalSymbols) .format(numericValue); } } private String createFillString(int numberOfDigits) { char[] filling = new char[numberOfDigits]; Arrays.fill(filling, '#'); return new String(filling); } public void setLocaleDecimalSymbols( DecimalFormatSymbols localeDecimalSymbols) { this.localeDecimalSymbols = localeDecimalSymbols; } }