XDocReport:通过在 ODT 文件中使用 Freemarker 填充表格来发布
XDocReport: Issue by filling tables with Freemarker in ODT-file
我试图从 XDocReport 文档重建示例,但是当我尝试创建表格或填充它们时。由于以下错误,它总是失败。我不知道是什么问题...
我已经更新了所有依赖项并在 .odt 文件中尝试了不同的语法。
错误:
Apr. 12, 2022 10:21:05 VORM. freemarker.log._JULLoggerFactory$JULLogger error
SEVERE: Error executing FreeMarker template
FreeMarker template error:
The following has evaluated to null or missing:
==> devs.name [in template "fr.opensagres.xdocreport.document.odt.ODTReport@57855c9a!content.xml" at line 5, column 11]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use [#if myOptionalVar??]when-present[#else]when-missing[/#if]. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${devs.name} auto-escaped [in template "fr.opensagres.xdocreport.document.odt.ODTReport@57855c9a!content.xml" at line 5, column 9]
----
Java stack trace (for programmers):
----
freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134)
at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:481)
at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:401)
at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:370)
at freemarker.core.BuiltInForLegacyEscaping._eval(BuiltInForLegacyEscaping.java:34)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.Expression.evalAndCoerceToStringOrUnsupportedMarkup(Expression.java:139)
at freemarker.core.BuiltInForString.getTargetString(BuiltInForString.java:34)
at freemarker.core.BuiltInForString._eval(BuiltInForString.java:29)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.MethodCall._eval(MethodCall.java:55)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.Expression.evalAndCoerceToStringOrUnsupportedMarkup(Expression.java:139)
at freemarker.core.BuiltInForString.getTargetString(BuiltInForString.java:34)
at freemarker.core.BuiltInForString._eval(BuiltInForString.java:29)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.MethodCall._eval(MethodCall.java:55)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.Expression.evalAndCoerceToStringOrUnsupportedMarkup(Expression.java:139)
at freemarker.core.BuiltInForString.getTargetString(BuiltInForString.java:34)
at freemarker.core.BuiltInForString._eval(BuiltInForString.java:29)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.MethodCall._eval(MethodCall.java:55)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:100)
at freemarker.core.DollarVariable.accept(DollarVariable.java:63)
at freemarker.core.Environment.visit(Environment.java:383)
at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:321)
at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:244)
at freemarker.core.Environment.visitIteratorBlock(Environment.java:657)
at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:108)
at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94)
at freemarker.core.Environment.visit(Environment.java:347)
at freemarker.core.Environment.visit(Environment.java:353)
at freemarker.core.Environment.visit(Environment.java:353)
at freemarker.core.Environment.process(Environment.java:326)
at fr.opensagres.xdocreport.template.freemarker.FreemarkerTemplateEngine.process(FreemarkerTemplateEngine.java:163)
at fr.opensagres.xdocreport.template.freemarker.FreemarkerTemplateEngine.processNoCache(FreemarkerTemplateEngine.java:122)
at fr.opensagres.xdocreport.template.AbstractTemplateEngine.process(AbstractTemplateEngine.java:118)
at fr.opensagres.xdocreport.template.AbstractTemplateEngine.process(AbstractTemplateEngine.java:83)
at fr.opensagres.xdocreport.document.AbstractXDocReport.processTemplateEngine(AbstractXDocReport.java:772)
at fr.opensagres.xdocreport.document.AbstractXDocReport.process(AbstractXDocReport.java:518)
at fr.opensagres.xdocreport.document.AbstractXDocReport.process(AbstractXDocReport.java:484)
at report_creation.fillList.main(fillList.java:51)
I am currently using this code:
fillList.java
public class fillList {
public static void main(String[] args) {
try {
// 1) Load ODT file by filling Velocity template engine and cache
// it to the registry
InputStream in = fillList.class.getResourceAsStream("Test.odt");
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
// 2) Create fields metadata to manage lazy loop (#foreach velocity)
// for table row.
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsList("developers.name");
metadata.addFieldAsList("developers.lastName");
metadata.addFieldAsList("developers.mail");
report.setFieldsMetadata(metadata);
// 3) Create context Java model
IContext context = report.createContext();
Project project = new Project("Create Dynamic Reports", 101);
context.put("project", project);
// Register developers list
List<Developer> developers = new ArrayList<>();
developers.add(new Developer("ZERR", "Angelo", "angelo.zerr@gmail.com"));
developers.add(new Developer("Leclercq", "Pascal", "pascal.leclercq@gmail.com"));
context.put("developers", developers);
// 4) Generate report by merging Java model with the ODT
OutputStream out = new FileOutputStream(new File("Test2_out.odt"));
report.process(context, out);
System.out.println("Report creation successfully completed!");
} catch (IOException e) {
System.err.println("[Debug Assistent]: No report created! >> IOException");
e.printStackTrace();
} catch (XDocReportException e) {
System.err.println("[Debug Assistent]: No report created! >> XDocReportException");
e.printStackTrace();
}
}
}
Project.java
public class Project {
private final String name;
private final Integer ID;
public Project(String name, Integer id) {
this.name = name;
this.ID = id;
}
public String getName() {
return name;
}
public Integer getID() {
return ID;
}
}
Developer.java
public class Developer {
private final String name;
private final String lastName;
private final String mail;
public Developer(String name, String lastName, String mail) {
this.name = name;
this.lastName = lastName;
this.mail = mail;
}
public String getFirstName() {
return name;
}
public String getLastName() {
return lastName;
}
public String getMail() {
return mail;
}
}
这是我正在使用的 .odt 文件。
在 Developer
class 中你有 getFirstName
而不是 getName
。因此 dev.name
将不起作用。
我试图从 XDocReport 文档重建示例,但是当我尝试创建表格或填充它们时。由于以下错误,它总是失败。我不知道是什么问题...
我已经更新了所有依赖项并在 .odt 文件中尝试了不同的语法。
错误:
Apr. 12, 2022 10:21:05 VORM. freemarker.log._JULLoggerFactory$JULLogger error
SEVERE: Error executing FreeMarker template
FreeMarker template error:
The following has evaluated to null or missing:
==> devs.name [in template "fr.opensagres.xdocreport.document.odt.ODTReport@57855c9a!content.xml" at line 5, column 11]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use [#if myOptionalVar??]when-present[#else]when-missing[/#if]. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${devs.name} auto-escaped [in template "fr.opensagres.xdocreport.document.odt.ODTReport@57855c9a!content.xml" at line 5, column 9]
----
Java stack trace (for programmers):
----
freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134)
at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:481)
at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:401)
at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:370)
at freemarker.core.BuiltInForLegacyEscaping._eval(BuiltInForLegacyEscaping.java:34)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.Expression.evalAndCoerceToStringOrUnsupportedMarkup(Expression.java:139)
at freemarker.core.BuiltInForString.getTargetString(BuiltInForString.java:34)
at freemarker.core.BuiltInForString._eval(BuiltInForString.java:29)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.MethodCall._eval(MethodCall.java:55)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.Expression.evalAndCoerceToStringOrUnsupportedMarkup(Expression.java:139)
at freemarker.core.BuiltInForString.getTargetString(BuiltInForString.java:34)
at freemarker.core.BuiltInForString._eval(BuiltInForString.java:29)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.MethodCall._eval(MethodCall.java:55)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.Expression.evalAndCoerceToStringOrUnsupportedMarkup(Expression.java:139)
at freemarker.core.BuiltInForString.getTargetString(BuiltInForString.java:34)
at freemarker.core.BuiltInForString._eval(BuiltInForString.java:29)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.MethodCall._eval(MethodCall.java:55)
at freemarker.core.Expression.eval(Expression.java:101)
at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:100)
at freemarker.core.DollarVariable.accept(DollarVariable.java:63)
at freemarker.core.Environment.visit(Environment.java:383)
at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:321)
at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:244)
at freemarker.core.Environment.visitIteratorBlock(Environment.java:657)
at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:108)
at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94)
at freemarker.core.Environment.visit(Environment.java:347)
at freemarker.core.Environment.visit(Environment.java:353)
at freemarker.core.Environment.visit(Environment.java:353)
at freemarker.core.Environment.process(Environment.java:326)
at fr.opensagres.xdocreport.template.freemarker.FreemarkerTemplateEngine.process(FreemarkerTemplateEngine.java:163)
at fr.opensagres.xdocreport.template.freemarker.FreemarkerTemplateEngine.processNoCache(FreemarkerTemplateEngine.java:122)
at fr.opensagres.xdocreport.template.AbstractTemplateEngine.process(AbstractTemplateEngine.java:118)
at fr.opensagres.xdocreport.template.AbstractTemplateEngine.process(AbstractTemplateEngine.java:83)
at fr.opensagres.xdocreport.document.AbstractXDocReport.processTemplateEngine(AbstractXDocReport.java:772)
at fr.opensagres.xdocreport.document.AbstractXDocReport.process(AbstractXDocReport.java:518)
at fr.opensagres.xdocreport.document.AbstractXDocReport.process(AbstractXDocReport.java:484)
at report_creation.fillList.main(fillList.java:51)
I am currently using this code:
fillList.java
public class fillList {
public static void main(String[] args) {
try {
// 1) Load ODT file by filling Velocity template engine and cache
// it to the registry
InputStream in = fillList.class.getResourceAsStream("Test.odt");
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
// 2) Create fields metadata to manage lazy loop (#foreach velocity)
// for table row.
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsList("developers.name");
metadata.addFieldAsList("developers.lastName");
metadata.addFieldAsList("developers.mail");
report.setFieldsMetadata(metadata);
// 3) Create context Java model
IContext context = report.createContext();
Project project = new Project("Create Dynamic Reports", 101);
context.put("project", project);
// Register developers list
List<Developer> developers = new ArrayList<>();
developers.add(new Developer("ZERR", "Angelo", "angelo.zerr@gmail.com"));
developers.add(new Developer("Leclercq", "Pascal", "pascal.leclercq@gmail.com"));
context.put("developers", developers);
// 4) Generate report by merging Java model with the ODT
OutputStream out = new FileOutputStream(new File("Test2_out.odt"));
report.process(context, out);
System.out.println("Report creation successfully completed!");
} catch (IOException e) {
System.err.println("[Debug Assistent]: No report created! >> IOException");
e.printStackTrace();
} catch (XDocReportException e) {
System.err.println("[Debug Assistent]: No report created! >> XDocReportException");
e.printStackTrace();
}
}
}
Project.java
public class Project {
private final String name;
private final Integer ID;
public Project(String name, Integer id) {
this.name = name;
this.ID = id;
}
public String getName() {
return name;
}
public Integer getID() {
return ID;
}
}
Developer.java
public class Developer {
private final String name;
private final String lastName;
private final String mail;
public Developer(String name, String lastName, String mail) {
this.name = name;
this.lastName = lastName;
this.mail = mail;
}
public String getFirstName() {
return name;
}
public String getLastName() {
return lastName;
}
public String getMail() {
return mail;
}
}
这是我正在使用的 .odt 文件。
在 Developer
class 中你有 getFirstName
而不是 getName
。因此 dev.name
将不起作用。