【问题标题】:Jasper Report Character Encoding in PDFJasper 报告 PDF 中的字符编码
【发布时间】:2013-07-13 06:35:50
【问题描述】:

我正在尝试在 jasper 报告中使用自定义字体。 Myanmar3 是缅甸的标准字体。 一切正常,但ReportTitle 必须是Myanmar FontMyanmar3Google 也使用Myanmar3 来表示缅甸语言环境。

将报告导出为html 文件时。它可以显示报告标题,很好。但是,导出的PDF文件不能显示错误。

在浏览器中。

在 PDF 中

public void report() throws Exception {
    List<SalesReport> saleReports = salesReportService.findSalesReport(new SalesReportCriteria());
    InputStream inputStream = new FileInputStream("report-template/saleReportTemplate.jrxml");
    String outputFilePdf = "D:/temp/BasicReport.pdf";
    String outputFileHtml = "D:/temp/BasicReport.html";
    Map paramMap = new HashMap();
    paramMap.put("ReportTitle", "\u1005\u101B\u1004\u103A\u1038\u1021\u1004\u103A\u1038\u1019\u103B\u102C\u1038\u1011\u100A\u103A\u101E\u103D\u1004\u103A\u1038\u1001\u103C\u1004\u103A\u1038");
    paramMap.put("TableDataSource", new JRBeanCollectionDataSource(saleReports));
    JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
    JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, paramMap, new JRBeanCollectionDataSource(saleReports));
    JasperExportManager.exportReportToPdfFile(jasperPrint, outputFilePdf);
    JasperExportManager.exportReportToHtmlFile(jasperPrint, outputFileHtml);
}

saleReportTemplate.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="TableReport" pageWidth="842" pageHeight="595" orientation="Landscape" whenNoDataType="AllSectionsNoDetail" columnWidth="802" 
              leftMargin="20" rightMargin="20" topMargin="30" bottomMargin="30" isFloatColumnFooter="true" whenResourceMissingType="Empty" uuid="a255c602-4ff1-4db8-ab72-65b5c3ff9bdd">

    <property name="ireport.zoom" value="1.0"/>
    <property name="ireport.x" value="0"/>
    <property name="ireport.y" value="0"/>
    <style name="Myanmar3" isDefault="true" fontName="Myanmar3" fontSize="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false"/>
    <style name="Table">
        <box leftPadding="0">
            <pen lineWidth="1.0" lineColor="#000000"/>
        </box>
    </style>
    <style name="TableHeader" mode="Opaque" backcolor="#808080"/>
    <style name="TableFooter" mode="Opaque" backcolor="#C0C0C0"/>
    <subDataset name="TableData" uuid="41cd3dac-2d22-41b9-9872-8fdb465d0f85">
        <field ... for table generation/>
    </subDataset>
    <parameter name="TableDataSource" class="net.sf.jasperreports.engine.JRDataSource"/>
    <parameter name="ReportTitle" class="java.lang.String" isForPrompting="false"/>
    <title>
        <band height="153">
            <textField isBlankWhenNull="true">
                <reportElement uuid="b44cb7c1-f7d5-467c-8982-b95f65dcb849" x="106" y="0" width="573" height="59"/>
                <textElement textAlignment="Center" verticalAlignment="Middle">
                    <font size="22" isBold="true" isPdfEmbedded="true"/>
                </textElement>
                <textFieldExpression><![CDATA[$P{ReportTitle}]]></textFieldExpression>
            </textField>
            <componentElement>
                -->other tag for table....
            </componentElement>
        </band>
    </title>
</jasperReport>

我已经添加了MYANMAR3.TTF 文件并在jasperreports-fonts-5.1.0.jar 中配置myanmar3 字体。

jasperreports_extension.properties

net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.dejavu=net/sf/jasperreports/fonts/fonts.xml
net.sf.jasperreports.extension.simple.font.families.myanmar3=net/sf/jasperreports/fonts/fonts.xml

字体.xml

...other default config.

<fontFamily name="Myanmar3">
    <normal>net/sf/jasperreports/fonts/myanmar3/MYANMAR3.TTF</normal>
    <bold>net/sf/jasperreports/fonts/myanmar3/MYANMAR3.TTF</bold>
    <italic>net/sf/jasperreports/fonts/myanmar3/MYANMAR3.TTF</italic>
    <boldItalic>net/sf/jasperreports/fonts/myanmar3/MYANMAR3.TTF</boldItalic>
    <pdfEncoding>Identity-H</pdfEncoding>
    <pdfEmbedded>true</pdfEmbedded>
</fontFamily>

我已经测试了很多配置、参考和示例。但是,对PDF 文件没有影响。

如果您有任何建议和提供,请告诉我。

【问题讨论】:

  • 您检查生成的 pdf 文件中的字体了吗?真的是Myanmar3吗?
  • @AlexK,是的,兄弟,我检查了 PDF 的属性。字体中的编码是 'Myanmar3'。
  • @AlexK,我会提交屏幕短吗?
  • 嗯...您是否尝试为 textField 元素设置样式(不使用默认样式)?
  • 是的,我试过了。

标签: java jasper-reports


【解决方案1】:

这是iText(版本测试5.5.4)和ttf字体的问题,itext 不支持连字,见下方评论

由于 jasper-reports 使用 itext 作为其库来呈现 pdf,因此您在 jasper 报告中无任何操作可以解决此问题。

使用仅 iText 的示例代码将呈现 与 jasper 报告相同的输出

public class FontTest {

    /** The resulting PDF file. */
    public static final String RESULT = "pdf/fontTest.pdf";
    /** Test text. */
    public static final String TEST = "\u1005\u101B\u1004\u103A\u1038\u1021\u1004\u103A\u1038\u1019\u103B\u102C\u1038\u1011\u100A\u103A\u101E\u103D\u1004\u103A\u1038\u1001\u103C\u1004\u103A\u1038";

    public void createPdf(String filename) throws IOException, DocumentException {
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        document.open();
        BaseFont bf = BaseFont.createFont(
            "lib/myanmar3.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font font = new Font(bf, 20);
        ColumnText column = new ColumnText(writer.getDirectContent());
        column.setSimpleColumn(36, 730, 569, 36);
        column.addElement(new Paragraph(TEST, font));
        column.go();
        document.close();
    }

    public static void main(String[] args) throws IOException, DocumentException {
        new FontTest().createPdf(RESULT);
    }
}

我在 部分发布了后续question 以了解为什么itext 无法正确呈现字体。

这是@Bruno Lowagie(iText 原开发者)的评论

“您看到的行为是由于 iText 不支持 连字。您需要 iText 的下一个未发布版本之一。 我们将在明年发布测试版,但仅限于客户。”

【讨论】:

  • 感谢您的解释。
【解决方案2】:

你能找出 Jasper-reports 使用的文本渲染引擎吗?

“Myanmar3”字体高度依赖于 OpenType 功能来生成正确的字符序列。在相当高的级别上,文本渲染引擎依赖于级别的例程来正确处理字体内的字形绘制。也就是说,在最高级别,您发出命令来绘制某个文本字符串。这个字符串被分解成单独的字符,然后可能会根据字体内部的 OTF 规则重新排序或替换为字形。只有在此之后,才会将正确的 glyphs 字符串(不再是“字符”)发回以进行显示。

从您的描述和屏幕截图看来,您的浏览器可以使用这种字体,但 Jasper-reports 不能。这在您的 PDF 中可见:您的输入字符串被正确分解(或者您可能以分解的形式提供)为单独的基本字形,但随后基本字形不会被文本渲染引擎替换回组合字形。因此,您的某些角色下方的虚线圆圈;这些只是占位符,从来都不是用来绘制的。

无法确定准确的故障点。字体“Myanmar3”包含cligliga 子表中的所有必要信息,这两个没有什么特别之处。然而,脚本标签mymr——可能文本渲染引擎不知道脚本的特定功能。另一种可能是它本身无法解释特征代码,因为这里似乎有很多复杂的链接上下文字符串。

我认为不能手动更改 Jasper-reports 的文本渲染引擎?您可能希望将此非常低级别问题转发给其开发人员。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多