如何在Velocity模板中格式化数字?

18

我在velocity模板中获取了一个Java对象。该对象有一个double值,我想将其格式化为小数点后两位,并在我的模板中显示。

我获取对象的类大致如下:

Class Price
{
double value;
String currency;
}

在我的velocity模板中,我是这样获取值的

$price.value

但是在显示之前,我需要将它格式化为2位小数。

我想把

23.59004转换成23.59

35.7转换成35.70

3.0转换成3.00

9转换成9.00

请告诉我如何在Velocity模板中实现它?我搜索了很多,发现可以使用Velocity Tools,但没有相关的示例?我能在模板中使用Velocity Tools吗?

7个回答

29

Velocity工具被期望在Velocity模板中使用;它们本质上是添加到模板中可用变量的对象,以便您可以使用$numberTool.format("#0.00",$val)或类似的语法。如果没有可用的工具符合您的需求,只需创建一个POJO并将其添加到模板即可。

为了使其工作,您还应该添加以下Maven依赖项:

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-tools</artifactId>
    <version>2.0</version>
</dependency>

并编写以下代码:

context.put("numberTool", new NumberTool());

2
我无法使用 $numberTool,它只是打印出 numberTool.format($val,"#0.00"),我需要包含什么吗? - Rajesh Pantula
1
请参考 'org.apache.velocity.tools.generic.NumberTool'。如果您正在使用 tools.xml 配置,请遵循 javadoc;如果没有,请创建一个新的 NumberTool 并将其添加到参数映射中。 - Tassos Bassoukos
3
哎呀,我没有查看Java文档,因为$numberTool.format($val,"#0.00")让我焦头烂额。实际上,正确的格式应该是:$numberTool.format("#0.00", $val)。请注意不要改变原意。 - TJ-
1
顺便提一下,如果该工具存在于类路径中,但之前没有放入速度上下文中,则仍然可以像这样使用:#set($numberTool=$anyPresentVar.class.forName('org.apache.velocity.tools.generic.NumberTool').newInstance())## - Vadzim
1
@Vazdim 如果速度得到了适当的保护,那就不会有问题。 - Tassos Bassoukos

24
#set($String = "abc")
$String.format("%.2f", $val)

$val在这种情况下必须是Double或Float类型...


1
确实,这个回答应该得到更多的+1。虽然它源自于"".someStringFunction()习语,在Velocity中不太明显,因为立即字符串不能像那样使用。为此设置一个变量并不优雅,但是,与其他大部分东西相比,它要简单得多...顺便说一句,这也适用于另一种常见但难以实现的事情:将数值类型转换为字符串类型,而不进行格式化,例如$myString.format("%d", $myNumeric) - mjv

3
使用VelocityTools项目中的MathTool。
$math.roundTo(2, $val)

2

formatCurrency($value)。这是一个很好的Java Velocity代码,可以将数字格式化为货币格式。


这应该是答案! - crystallove18

1

只使用Java格式化程序的解决方案:(无需额外库)

NumberFormat decimalFormat = new DecimalFormat("#.00");
velocityContext.put("decimalFormat", decimalFormat);

Int Number: $decimalFormat.format($obj.intNum)

以下是时间戳转换为人类可读日期的格式。
DateFormat DATETIME_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
velocityContext.put("datetimeFormat", DATETIME_FORMAT);

Timestamp to Date: $datetimeFormat.format($obj.timestamp)

请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不要将其作为首选项。而且不要毫无保留地使用它。我们在java.time,现代Java日期和时间API中有更好的选择,以及它的DateTimeFormatter - Ole V.V.
1
完全同意你的看法 @OleV.V. - 这里的想法是提供一种方式,使得这些格式化程序来自JDK本身,而不是使用额外的库。人们可以使用最适合他们的任何东西。 - Maqbool Ahmed

0

$numberTool.format("#0.00", $val)

的意思是格式化数值 $val 为保留两位小数的字符串。


0
除了使用$numberTool.format之外,更好的做法是使用基于MessageFormat的工具类,这些工具类不仅仅处理数字。例如,我们使用的是Struts特定的MessageTool,但你也可以使用类似的ResourceTool代替:
resources.properties
some.key=The price is currently {0,number,$#.##}

template.vm
<p>
  $msg.get('some.key', 'resources', [$price])
</p>

通过这种方式,您可以获得数字的上下文而不仅仅是单独的数字。在非英语语言中,数字可能更适合出现在文本左侧、中间或其他位置。这比仅仅格式化数字要灵活得多。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接