如何用模式格式化 java.time.LocalDateTime 和 java.time.LocalDate?
How to format java.time.LocalDateTime and java.time.LocalDate with pattern?
下面截取了属性$F
是classjava.time.LocalDateTime
或java.time.LocalDate
.
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[$F{theLocalDateTime}]]></textFieldExpression>
</textField>
如何在 jasper 报告中使用 textField pattern
格式化这个 属性?
要在当前版本的 jasper-report 中为 Date/Time 对象使用 pattern 属性,您需要 java.util.Date
class 或以下之一低于classes.
解决方法是将java.time.LocalDate
和java.time.LocalDateTime
转换
正在转换为 java.util.Date
from java.time.LocalDate
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.util.Date.from($F{theLocalDate}.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant())]]></textFieldExpression>
</textField>
from java.time.LocalDateTime
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.util.Date.from($F{theLocalDateTime}.atZone(java.time.ZoneId.systemDefault()).toInstant())]]></textFieldExpression>
</textField>
Converting to java.sql.Timestamp
来自 java.time.LocalDate
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.sql.Timestamp.valueOf($F{theLocalDate}.atStartOfDay())]]></textFieldExpression>
</textField>
来自 java.time.LocalDateTime
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.sql.Timestamp.valueOf($F{theLocalDateTime})]]></textFieldExpression>
</textField>
Note: Applying pattern is always preferable solution, specially when
exporting to excel since correct class will be passed to poi (hence
excel will recognize column as a date and apply same formatting as in
pattern)
由于 java.time
模块有点复杂和冗长,我通常会创建一些变量来保存已编译的 DateTimeFormatter 以供进一步使用。
我希望我的报告适应任何语言环境,所以我不使用字符串文字进行格式化。
我正在使用报告区域设置,但您可以使用 java.util.Locale.forLanguageTag("en-US")
选择您的区域设置。
如果需要,您也可以更改 java.time.format.FormatStyle
LocalDate 格式化程序:
<variable name="dateFormatter" class="java.time.format.DateTimeFormatter">
<variableExpression><![CDATA[java.time.format.DateTimeFormatter
.ofLocalizedDate(java.time.format.FormatStyle.SHORT)
.withLocale($P{REPORT_LOCALE})
.withChronology(java.time.chrono.Chronology.ofLocale($P{REPORT_LOCALE}))]]></variableExpression>
</variable>
LocalDateTime 格式化程序:
<variable name="dateTimeFormatter" class="java.time.format.DateTimeFormatter">
<variableExpression><![CDATA[java.time.format.DateTimeFormatter
.ofLocalizedDateTime(java.time.format.FormatStyle.SHORT)
.withLocale($P{REPORT_LOCALE})
.withChronology(java.time.chrono.Chronology.ofLocale($P{REPORT_LOCALE}))]]></variableExpression>
</variable>
现在我可以这样格式化 LocalDate 字段:
$F{localDateField}.format($V{dateFormatter})
还有这样一个 LocalDateTime 字段:
$F{localDateTimeField}.format($V{dateTimeFormatter})
我遇到了同样的问题,我通过向 JasperReports 引入自定义函数解决了这个问题。所以最后它可以在 LocalDate、LocalTime、LocalDateTime 上用作以下任何实现 TemporalAccessor 的东西:
FORMAT_DATETIME($F{someLocalDate}, "dd.MM.yyyy")
FORMAT_DATETIME($F{someLocalDateTime}, "dd.MM.yyyy HH:mm")
FORMAT_DATETIME($F{someLocalTime}, "HH:mm")
为此创建以下文件:
函数类别。这是必需的,以便 jasper 报告设计器的表达式编辑器在设置类别下显示该功能
package org.example.jrfunctions;
import net.sf.jasperreports.functions.annotations.FunctionCategory;
@FunctionCategory()
public class LocalDateTime {
}
Class 具有功能(可以添加更多功能)
package org.example.jrfunctions;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import net.sf.jasperreports.functions.annotations.Function;
import net.sf.jasperreports.functions.annotations.FunctionCategories;
import net.sf.jasperreports.functions.annotations.FunctionParameter;
import net.sf.jasperreports.functions.annotations.FunctionParameters;
@FunctionCategories({
org.example.jrfunctions.LocalDateTime.class })
public class JRDateTimeFunctions {
@Function("FORMAT_DATETIME")
@FunctionParameters({
@FunctionParameter("temporalObject"),
@FunctionParameter("format")
})
public static String FORMAT_DATETIME(TemporalAccessor temporalObject, String format) {
if (temporalObject == null) {
return null;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
return formatter.format(temporalObject);
}
}
下面的文件需要和上面两个在同一个目录下,并且需要设置每个参数的所有属性。否则 jasper 报表设计器将不会在表达式编辑器中显示自定义函数:
jasperreports_messages.properties
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.description = Formats the Temporal Object according to format
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.name = Format Temporal Accessor (Object)
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.temporalObject.name = Temporal Accessor
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.temporalObject.description = Object to format
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.format.name = Format
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.format.description = Fromat
org.example.jrfunctions.LocalDateTime.name=Local Date & Time
org.example.jrfunctions.LocalDateTime.description=
以下文件需要在类路径中。我把它放到 src/main/resources
jasperreports_extension.properties
net.sf.jasperreports.extension.registry.factory.functions=net.sf.jasperreports.functions.FunctionsRegistryFactory
net.sf.jasperreports.extension.functions.jrdatetimefunctions=org.example.jrfunctions.JRDateTimeFunctions
现在自定义函数应该显示在表达式编辑器中,编译没有任何问题。
更多信息:
下面截取了属性$F
是classjava.time.LocalDateTime
或java.time.LocalDate
.
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[$F{theLocalDateTime}]]></textFieldExpression>
</textField>
如何在 jasper 报告中使用 textField pattern
格式化这个 属性?
要在当前版本的 jasper-report 中为 Date/Time 对象使用 pattern 属性,您需要 java.util.Date
class 或以下之一低于classes.
解决方法是将java.time.LocalDate
和java.time.LocalDateTime
正在转换为 java.util.Date
from java.time.LocalDate
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.util.Date.from($F{theLocalDate}.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant())]]></textFieldExpression>
</textField>
from java.time.LocalDateTime
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.util.Date.from($F{theLocalDateTime}.atZone(java.time.ZoneId.systemDefault()).toInstant())]]></textFieldExpression>
</textField>
Converting to java.sql.Timestamp
来自 java.time.LocalDate
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.sql.Timestamp.valueOf($F{theLocalDate}.atStartOfDay())]]></textFieldExpression>
</textField>
来自 java.time.LocalDateTime
<textField pattern="EE. dd.MM.yyyy">
<reportElement...>
</reportElement>
<textFieldExpression><![CDATA[java.sql.Timestamp.valueOf($F{theLocalDateTime})]]></textFieldExpression>
</textField>
Note: Applying pattern is always preferable solution, specially when exporting to excel since correct class will be passed to poi (hence excel will recognize column as a date and apply same formatting as in pattern)
由于 java.time
模块有点复杂和冗长,我通常会创建一些变量来保存已编译的 DateTimeFormatter 以供进一步使用。
我希望我的报告适应任何语言环境,所以我不使用字符串文字进行格式化。
我正在使用报告区域设置,但您可以使用 java.util.Locale.forLanguageTag("en-US")
选择您的区域设置。
如果需要,您也可以更改 java.time.format.FormatStyle
LocalDate 格式化程序:
<variable name="dateFormatter" class="java.time.format.DateTimeFormatter">
<variableExpression><![CDATA[java.time.format.DateTimeFormatter
.ofLocalizedDate(java.time.format.FormatStyle.SHORT)
.withLocale($P{REPORT_LOCALE})
.withChronology(java.time.chrono.Chronology.ofLocale($P{REPORT_LOCALE}))]]></variableExpression>
</variable>
LocalDateTime 格式化程序:
<variable name="dateTimeFormatter" class="java.time.format.DateTimeFormatter">
<variableExpression><![CDATA[java.time.format.DateTimeFormatter
.ofLocalizedDateTime(java.time.format.FormatStyle.SHORT)
.withLocale($P{REPORT_LOCALE})
.withChronology(java.time.chrono.Chronology.ofLocale($P{REPORT_LOCALE}))]]></variableExpression>
</variable>
现在我可以这样格式化 LocalDate 字段:
$F{localDateField}.format($V{dateFormatter})
还有这样一个 LocalDateTime 字段:
$F{localDateTimeField}.format($V{dateTimeFormatter})
我遇到了同样的问题,我通过向 JasperReports 引入自定义函数解决了这个问题。所以最后它可以在 LocalDate、LocalTime、LocalDateTime 上用作以下任何实现 TemporalAccessor 的东西:
FORMAT_DATETIME($F{someLocalDate}, "dd.MM.yyyy")
FORMAT_DATETIME($F{someLocalDateTime}, "dd.MM.yyyy HH:mm")
FORMAT_DATETIME($F{someLocalTime}, "HH:mm")
为此创建以下文件:
函数类别。这是必需的,以便 jasper 报告设计器的表达式编辑器在设置类别下显示该功能
package org.example.jrfunctions;
import net.sf.jasperreports.functions.annotations.FunctionCategory;
@FunctionCategory()
public class LocalDateTime {
}
Class 具有功能(可以添加更多功能)
package org.example.jrfunctions;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import net.sf.jasperreports.functions.annotations.Function;
import net.sf.jasperreports.functions.annotations.FunctionCategories;
import net.sf.jasperreports.functions.annotations.FunctionParameter;
import net.sf.jasperreports.functions.annotations.FunctionParameters;
@FunctionCategories({
org.example.jrfunctions.LocalDateTime.class })
public class JRDateTimeFunctions {
@Function("FORMAT_DATETIME")
@FunctionParameters({
@FunctionParameter("temporalObject"),
@FunctionParameter("format")
})
public static String FORMAT_DATETIME(TemporalAccessor temporalObject, String format) {
if (temporalObject == null) {
return null;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
return formatter.format(temporalObject);
}
}
下面的文件需要和上面两个在同一个目录下,并且需要设置每个参数的所有属性。否则 jasper 报表设计器将不会在表达式编辑器中显示自定义函数:
jasperreports_messages.properties
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.description = Formats the Temporal Object according to format
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.name = Format Temporal Accessor (Object)
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.temporalObject.name = Temporal Accessor
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.temporalObject.description = Object to format
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.format.name = Format
org.example.jrfunctions.JRDateTimeFunctions.FORMAT_DATETIME.format.description = Fromat
org.example.jrfunctions.LocalDateTime.name=Local Date & Time
org.example.jrfunctions.LocalDateTime.description=
以下文件需要在类路径中。我把它放到 src/main/resources
jasperreports_extension.properties
net.sf.jasperreports.extension.registry.factory.functions=net.sf.jasperreports.functions.FunctionsRegistryFactory
net.sf.jasperreports.extension.functions.jrdatetimefunctions=org.example.jrfunctions.JRDateTimeFunctions
现在自定义函数应该显示在表达式编辑器中,编译没有任何问题。
更多信息: