XDocReport 将 odt 转换为 pdf 如何设置正确的语言环境
Posted
技术标签:
【中文标题】XDocReport 将 odt 转换为 pdf 如何设置正确的语言环境【英文标题】:XDocReport converting odt to pdf how to set proper locale 【发布时间】:2020-03-25 21:41:57 【问题描述】:我正在尝试使用 IXDocReport 将一些 *.odt
文件转换为 *.pdf
。
这是*.odt
文件的假设内容:$amount?string.currency to be paid
这是我用来转换的代码(你可以在 kotlin REPL 中运行它):
import fr.opensagres.xdocreport.converter.ConverterTypeTo
import fr.opensagres.xdocreport.converter.ConverterTypeVia
import fr.opensagres.xdocreport.converter.Options
import fr.opensagres.xdocreport.document.IXDocReport
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry
import fr.opensagres.xdocreport.template.TemplateEngineKind
import java.io.ByteArrayInputStream
import java.io.File
val options: Options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.ODFDOM)
val content: ByteArray = File("/home/sandro/tmp/report.odt").readBytes()
val templateId: String = "someId"
val registry: XDocReportRegistry = XDocReportRegistry.getRegistry()
val data: MutableMap<String, Any> = mutableMapOf("amount" to 10)
ByteArrayInputStream(content).use input ->
val report: IXDocReport =
registry.loadReport(input, templateId, TemplateEngineKind.Freemarker, true)
val tmpFile: File = createTempFile("out", ".pdf")
tmpFile.outputStream().use output ->
report.convert(data, options, output)
println(tmpFile.toString())
结果是带有字符串$10.00 to be paid
的pdf文件
如何在转换过程中将所需的语言环境设置为 XDocReport,以便将结果正确更改为其他货币?
P.S.我无法控制模板本身 - 所以请不要告诉我在模板本身添加 <#setting locale="$bean.locale">
或其他内容。我唯一可以更改的地方是代码。提前致谢。
P.P.S.我需要为每个请求渲染许多模板,并且需要为每个模板设置区域设置。
【问题讨论】:
【参考方案1】:我从未使用过 XDocReport,但也许这会起作用:https://github.com/opensagres/xdocreport/wiki/FreemarkerTemplate“如何配置 Freemarker?”
来自那里的报价:
要使用 XDocReport 配置 Freemarker,您必须获取配置实例。要做到 > 你必须这样做
创建一个类(例如: fr.opensagres.xdocreport.MyFreemarkerConfiguration) 实现 fr.opensagres.xdocreport.document.discovery.ITemplateEngineInitializerDiscovery。 通过创建文件向 SPI 注册此类 META-INF/services/fr.opensagres.xdocreport.document.discovery.ITemplateEngineInitializerDiscovery 用你班级的名字: fr.opensagres.xdocreport.MyFreemarkerConfiguration 这个文件应该是 在您的类路径中(例如,您可以将它托管在 src/META-INF/services/ 的项目)。
所以你需要这样一个类:
public class MyFreemarkerConfiguration implements ITemplateEngineInitializerDiscovery
[...]
public void initialize(ITemplateEngine templateEngine)
if (TemplateEngineKind.Freemarker.name().equals( templateEngine.getKind()))
Configuration cfg = ((FreemarkerTemplateEngine) templateEngine).getFreemarkerConfiguration();
cfg.setLocale(...);
【讨论】:
谢谢,这个看起来不错,我去看看。但是如何根据请求更改语言环境? 虽然 FreeMarker 支持每个请求的语言环境(既作为Configuration.getTemplate
参数,也通过在模板处理的Environment
中设置语言环境),我不知道 XDocReport 是否提供任何钩子。如果没有,那么也许您可以通过在Configuration
中设置的自动包含来引入一些技巧,然后在自动包含的模板中调用一个 Java 实用程序来获取所需的语言环境(从线程本地等),并将其设置为当前的Environment
(您可以通过Environment.getCurrentEnvironment()
获得)。无论如何,您应该根据什么来决定请求的语言环境?
它来自通过方法参数使用我的库的应用程序,对于同一个实例,根据请求可能有很多不同的语言环境。
您能否将变量放入每个请求的数据模型中?然后您可以将所需的设置放入地图中,然后在自动包含的模板中选择它并将它们应用到Envionment
。如果您不控制数据模型,线程局部变量可能仍可用于相同目的。当然,如果 XDocReport 允许您在处理模板之前指定设置 Environment
的内容,那么最简洁的方法是......但如果他们不这样做,自动包含是解决方法。以上是关于XDocReport 将 odt 转换为 pdf 如何设置正确的语言环境的主要内容,如果未能解决你的问题,请参考以下文章
xml 使用apche poi,xdocreport和itext扩展将Docx转换为PDF
在 Windows 上使用 Openoffice 将 ODT 转换为 PDF