使用XDocReport结合FieldsMetadata与Velocity生成Docx表格时单元格显示异常问题求助
解决XDocReport+Velocity生成Docx表格时显示对象而非字段值的问题
我帮你排查下问题根源,这大概率是模板字段引用方式不对,或者XDocReport的元数据配置没正确识别列表字段导致的,一步步来解决:
1. 核心问题分析
当你直接在模板里写$codes或者字段引用格式错误时,Velocity会默认输出对象的toString()结果(也就是Kotlin数据类自带的Code(code=xxx, libelle=xxx...)格式),而不是你需要的具体字段值。解决关键是正确遍历列表并引用每个对象的字段。
2. 修正Word模板(code.docx)
你需要在Word模板里配置正确的Velocity循环语法和字段引用:
- 先在Word中创建表格,保留一行作为循环模板行,列数对应
Code类的6个字段; - 在表格上方添加循环起始标记:
#foreach($code in $codes); - 在模板行的每个单元格里,分别填入对应的字段引用:
- 第一格:
$code.code - 第二格:
$code.libelle - 第三格:
$code.base - 第四格:
$code.taux - 第五格:
$code.gain - 第六格:
$code.retenue
- 第一格:
- 在表格下方添加循环结束标记:
#end
注意:这些标记直接作为普通文本输入Word即可,不需要用XDocReport的字段插入工具,Velocity会自动识别这些语法。
3. 确认FieldsMetadata配置
你的代码里metadata.load("codes", Code::class.java, true)是正确的,第三个参数true会自动加载Code类的所有字段到元数据中。如果自动加载有异常,你可以手动指定字段来确保映射生效:
val metadata = report.createFieldsMetadata() metadata.load("codes", Code::class.java) // 手动声明每个需要的列表字段 metadata.addFieldAsList("codes.code") metadata.addFieldAsList("codes.libelle") metadata.addFieldAsList("codes.base") metadata.addFieldAsList("codes.taux") metadata.addFieldAsList("codes.gain") metadata.addFieldAsList("codes.retenue")
这样能明确告诉XDocReport,codes列表中每个元素的这些字段需要被解析。
4. 验证数据传递正确性
确保getAllCodes()返回的确实是List<Code>类型,且每个对象的字段都有有效值。可以加个日志验证:
val codesList = getAllCodes() codesList.forEach { println("Code数据:${it.code} - ${it.libelle}") } context.put("codes", codesList)
5. 测试生成结果
修改完模板和代码后重新生成Docx,此时每个单元格应该会显示对应的字段值,而非对象本身。如果还是有问题,检查模板里的Velocity语法是否拼写正确(比如#foreach和#end有没有写错),字段名是否和Code类的属性完全一致(Velocity对大小写敏感!)。
内容的提问来源于stack exchange,提问作者Ismael




