Как контролировать значимые цифры, только при необходимости, в шаблоне Thymeleaf?

при использовании th:text атрибут чтобы оценить и отобразить числовое поле, Thymeleaf отображает полное количество доступных цифр. Например, это:

<span th:text="${user.averageScore}"/>

... может отображаться на экране браузера:

107.54896

Я хотел бы отобразить эту сумму, округленную не более чем до двух знаков после запятой. Из документации Thymeleaf, это:

<span th:text="${#numbers.formatDecimal(user.averageScore, 0, 2)}"/>

... изменяет вывод следующим образом:

107.55

однако, есть ли способ сделать это более гибко... в случаях, когда значение имеет менее двух знаков после запятой? Я хочу удалить только десятичные знаки, чтобы сократить до двух. Я никогда не хочу добавлять десятичные знаки, чтобы получить до двух. Если поле выше имеет значение 107, то оно будет отображаться как:

107.00

как я могу сделать номера формата Thymeleaf для двух десятичных знаков или меньше... вместо двух знаков после запятой, несмотря ни на что?

2 ответов


привет, вы можете попробовать что-то вроде этого.

<span th:text="${user.averageScore} % 1 == 0? ${user.averageScore} :${#numbers.formatDecimal(user.averageScore, 0, 2)}"/>

в Thymeleaf 2.1 нет простого способа сделать это, но есть два трудных способа.

Hard way #1: Fork Thymeleaf и добавьте метод format в класс org.thymeleaf.выражение.Числа, которые делают то, что вы хотите (добавление метода, который принимает шаблон DecimalFormat, будет выглядеть как логическое расширение)

Hard way #2: Добавьте диалект в Thymeleaf, который предоставляет новый класс выражений, который выполняет форматирование, которое вы хотите. Мой пример ниже основан на использовании Spring с Thymeleaf чтобы зарегистрировать диалект для форматирования чисел, представляющих часы.

Шаг 1: зарегистрируйте диалект:

@Component
public class ThymeLeafSetup implements InitializingBean {

@Autowired
private SpringTemplateEngine templateEngine;

@Override
public void afterPropertiesSet() throws Exception {
    templateEngine.addDialect(new HoursDialect());
}
}

Шаг #2: Создайте класс диалекта (логика форматирования, делегированная статическому методу TimeUtils) - на основе Java8TimeDialect:

public class HoursDialect extends AbstractDialect implements IExpressionEnhancingDialect {
public static class Hours {
    public String format(BigDecimal hours) {
        return TimeUtils.formatHours(hours);
    }
}

@Override
public String getPrefix() {
    // No attribute or tag processors, so we don't need a prefix at all and
    // we can return whichever value.
    return "hours";
}

@Override
public boolean isLenient() {
    return false;
}

@Override
public Map<String, Object> getAdditionalExpressionObjects(IProcessingContext processingContext) {
    return Collections.singletonMap("hours", new Hours());
}
}

Шаг #3: Создайте логику форматирования на основе DecimalFormat

public class TimeUtils {

public static String formatHours(BigDecimal hours) {
    DecimalFormat format = new DecimalFormat("#0.##");
    format.setGroupingUsed(true);
    format.setGroupingSize(3);
    return format.format(hours);
}
}

Шаг #4: тесты логики форматирования

@Test
public void formatDecimalWilLFormatAsExpected() {
    verifyHourNumberFormatsAsExpected("1.5", "1.5");
    verifyHourNumberFormatsAsExpected("1.25", "1.25");
    verifyHourNumberFormatsAsExpected("123.0", "123");
    verifyHourNumberFormatsAsExpected("1230", "1,230");
}

void verifyHourNumberFormatsAsExpected(String number, String expected) {
    assertThat(TimeUtils.formatHours(new BigDecimal(number))).isEqualTo(expected);
}