2

我有一个模型类,其中包含ZonedDateTime类型的字段。生成报表数据时显示为:

2017-08-17T16:09:03+03:00[欧洲/基希讷乌]

要格式化该日期,我使用方法setPattern("dd.MM.yyyy")但没有任何变化。

所有东西都是通过反射生成的,检查源:

for (Field field : entityClass.getDeclaredFields()) {
    String fieldName = field.getName();
    if (usedFields.contains(fieldName)) {
        field.setAccessible(true);
        if(field.getType().isAssignableFrom(Date.class) || field.getType().isAssignableFrom(ZonedDateTime.class)){
            report.addColumn(Columns.column(fieldName, fieldName, field.getType()).setPattern("dd.MM.yyyy"));
        }else {
            report.addColumn(Columns.column(fieldName, fieldName, field.getType()));
        }
    }
}

生成报告,其中列表是元素的通用列表。

report
.title(
        Components.text("Documents Report")
        .setStyle(getHeaderCenteredBoldStyle())
        .setHorizontalTextAlignment(HorizontalTextAlignment.CENTER))
        .pageFooter(Components.pageXofY())
.setColumnTitleStyle(getColumnTitleStyle())
.highlightDetailEvenRows()
.setDataSource(list);

生成的 PDF

生成的pdf 有任何想法吗?

4

1 回答 1

3

似乎setPattern适用于java.util.Date,但不适用于java.time.ZonedDateTime。我创建了一个简单的实体:

public class Entity {

    private ZonedDateTime zonedDateTime = ZonedDateTime.parse("2017-08-17T16:09:03+03:00[Europe/Chisinau]");

    private Date date = new Date();

    // getters and setters
}

然后我使用您的代码 ( for (Field field : entityClass.getDeclaredFields()) etc) 添加列。对于数据源list,我手动创建了它,只是为了测试:

DRDataSource ds = new DRDataSource("zonedDateTime", "date");
ds.add(entity.getZonedDateTime(), entity.getDate());

在生成的报告中,ZonedDateTime未格式化(显示为2017-08-17T16:09:03+03:00[Europe/Chisinau]),但Date正确显示为21.08.2017

解决此问题的一种方法是设置值格式化程序并使用 ajava.time.format.DateTimeFormatter将其转换ZonedDateTime为 a String

if (field.getType().isAssignableFrom(ZonedDateTime.class)) {
    // ZonedDateTime, use a value formatter
    report.addColumn(Columns.column(fieldName, fieldName, ZonedDateTime.class)
        // set a custom value formatter
        .setValueFormatter(new AbstractValueFormatter<String, ZonedDateTime>() {
            @Override
            public String format(ZonedDateTime value, ReportParameters reportParameters) {
                // convert ZonedDateTime to dd.MM.yyyy format
                DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd.MM.yyyy");
                return value.format(fmt);
            }
        }));
} else if (field.getType().isAssignableFrom(Date.class)) {
    // java.util.Date: setPattern works
    report.addColumn(Columns.column(fieldName, fieldName, field.getType()).setPattern("dd.MM.yyyy"));
...

有了这个, 以ZonedDateTime定义的格式显示DateTimeFormatter

17.08.2017

在这个例子中,我创建了DateTimeFormatter内部类,但最好只在外部创建一个格式化程序if(它可以在一个static final字段中,因为它是不可变的和线程安全的)并在你的应用程序中重用它。


另一种选择是手动将 格式化ZonedDateTime为 a String,使用相同的java.time.format.DateTimeFormatter,但在数据源列表中。我还必须将列的类型更改为String(在内部for):

if (field.getType().isAssignableFrom(ZonedDateTime.class)) {
    // ZonedDateTime, manually convert to String
    report.addColumn(Columns.column(fieldName, fieldName, String.class));
} else if (field.getType().isAssignableFrom(Date.class)) {
    // java.util.Date: setPattern works
    report.addColumn(Columns.column(fieldName, fieldName, field.getType()).setPattern("dd.MM.yyyy"));
} else {
    report.addColumn(Columns.column(fieldName, fieldName, field.getType()));
}

然后,在数据源list中,我不得不使用 将DateTimeFormatter其格式化ZonedDateTimeString

// create formatter
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd.MM.yyyy");

// format the ZonedDateTime
ds.add(entity.getZonedDateTime().format(fmt), entity.getDate());

有了这个,ZonedDateTime现在显示为17.08.2017

我不确定您是如何创建list值的,但您必须将其更改为以ZonedDateTime上述方式格式化(或在实体内部进行)。

于 2017-08-21T13:50:03.680 回答