我们使用 Jaspersoft iReport Designer 创建双语 PDF 输出——每个文件都包含英语和法语文本。
出于可访问性的原因,我们希望在生成的 PDF 中用适当的语言标记每个文本块。请参阅PDF19:使用 PDF 文档中的 Lang 条目指定段落或短语的语言,了解我们正在尝试做的事情。
手动修改 PDF 文件不是一种选择,因为我们直接通过电子邮件将它们发送给我们的用户。
Jaspersoft 支持这个吗?
我们使用 Jaspersoft iReport Designer 创建双语 PDF 输出——每个文件都包含英语和法语文本。
出于可访问性的原因,我们希望在生成的 PDF 中用适当的语言标记每个文本块。请参阅PDF19:使用 PDF 文档中的 Lang 条目指定段落或短语的语言,了解我们正在尝试做的事情。
手动修改 PDF 文件不是一种选择,因为我们直接通过电子邮件将它们发送给我们的用户。
Jaspersoft 支持这个吗?
没有 JasperReports 版本<=6.7.0不支持这一点,配置参考中没有可用的属性将Lang
属性设置为单个 textElement。
您有 2 个选项:
使用 Dave Jarvis建议的例如 iText 发布 pdf 文件。您可以尝试更改字典或重新创建 pdf 添加此附加信息。这些方法都相当复杂,而且运行时间自然会增加,因为您需要阅读/重新创建 pdf。
修改JasperReport 的源代码以添加支持。直接修改 JRPdfExporter、JRPdfExporterTagHelper 或添加新的导出器(以保持原始库不变)
在这个答案中,我将向您展示如何修改原始库添加额外的标签(在字典中添加 LANG 条目)
PDF19中的示例:使用 PDF 文档中的 Lang 条目指定段落或短语的语言,使用 iText RUPS 显示此 PDF 对象树。
我会假设/Lang
在我们的输出中添加与不是默认语言的特定文本相关的输出就足够了。注意:如果您还需要添加其他条目,技术保持不变,您只需修改以下代码示例。
net.sf.jasperreports.export.pdf.tag.lang
如果该属性存在于类型文本字段中的 reportElement 上,则添加一个新属性,将/Lang
具有其值的条目添加到字典中。
对JRPdfExporterTagHelper.java的修改
添加静态属性标识符以遵循代码样式
public static final String PROPERTY_TAG_LANG = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.lang";
修改startText(boolean isHyperLink)
andstartText(String text, boolean isHyperlink)
,本例只显示第一种方法(原理与第二种相同),我们需要更改方法签名添加JRPrintText
,以便我们可以检索属性。
protected void startText(JRPrintText text, boolean isHyperlink)
{
if (isTagged)
{
PdfStructureElement textTag = new PdfStructureElement(tagStack.peek(), isHyperlink ? PdfName.LINK : PdfName.TEXT);
if (text.hasProperties()&&text.getPropertiesMap().containsProperty(PROPERTY_TAG_LANG)){
textTag.put(PdfName.LANG, new PdfString(text.getPropertiesMap().getProperty(PROPERTY_TAG_LANG)));
}
pdfContentByte.beginMarkedContentSequence(textTag);
}
}
由于我们更改了方法签名,我们现在需要修改JRPdfExporter.java以便我们可以重新编译
调整exportText(JRPrintText text)
...
if (glyphRendererAddActualText && textRenderer instanceof PdfGlyphRenderer)
{
tagHelper.startText(text,styledText.getText(), text.getLinkType() != null);
}
else
{
tagHelper.startText(text,text.getLinkType() != null);
}
...
您可以删除 boolean text.getLinkType() != null
,因为我们现在实际上是在传递文本对象,但为了简单起见,我想保留类似的代码
jrxml
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="TaggedPdf" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="1be2df3d-cbc1-467c-8729-1ed569eb8a0d">
<property name="net.sf.jasperreports.export.pdf.tagged" value="true"/>
<property name="net.sf.jasperreports.export.pdf.tag.language" value="EN-US"/>
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<queryString>
<![CDATA[]]>
</queryString>
<title>
<band height="67" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="240" height="30" uuid="0722eadc-3fd6-4c4d-811c-64fbd18e0af5"/>
<textElement verticalAlignment="Middle"/>
<text><![CDATA[Hello world]]></text>
</staticText>
<staticText>
<reportElement x="0" y="30" width="240" height="30" uuid="5080190e-e9fd-4df6-b0f6-f1be3c109805">
<property name="net.sf.jasperreports.export.pdf.tag.lang" value="FR"/>
</reportElement>
<textElement verticalAlignment="Middle"/>
<text><![CDATA[Bonjour monde]]></text>
</staticText>
</band>
</title>
</jasperReport>
通过上述修改导出为 pdf 并使用 iText RUPS 进行可视化
根据PDF19 是否足够:使用 PDF 文档中的 Lang 条目指定段落或短语的语言
验证与周围文本语言不同的段落、短语或单词的语言是否由封闭标记或容器上的 /Lang 条目正确指定:
据我所知,是的,但我不是这方面的专家,无论如何,如果您需要添加其他标签,过程是相同的。