如果缺少PDF的字体,为什么jasper报告不会抛出JRFontNotFoundException?

dur*_*dur 4 java fonts pdf-generation jasper-reports export-to-pdf

我读

我希望Jasper Reports会抛出一个JRFontNotFoundException如果机器上没有安装字体的话.

但我的应用程序并没有抛出JRFontNotFoundException,虽然我没有在任何(Jaspersoft Studios,JasperReports,Adobe Acrobat Reader)机器上安装使用过的字体"Helvetica".

JRXML:

<parameter name="timestamp" class="java.util.Date"/>
[...]
<textField>
    <reportElement x="0" y="0" width="50" height="16" uuid="0007846a-26f1-457a-a198-67a2f7c8417c">
        <property name="local_mesure_unitwidth" value="pixel"/>
        <property name="com.jaspersoft.studio.unit.width" value="px"/>
        <property name="local_mesure_unitx" value="pixel"/>
        <property name="com.jaspersoft.studio.unit.x" value="px"/>
        <property name="local_mesure_unity" value="pixel"/>
        <property name="com.jaspersoft.studio.unit.y" value="px"/>
        <property name="local_mesure_unitheight" value="pixel"/>
        <property name="com.jaspersoft.studio.unit.height" value="px"/>
    </reportElement>
    <box padding="2"/>
    <textElement textAlignment="Left" verticalAlignment="Top">
        <font size="8" pdfFontName="Helvetica" pdfEncoding="Cp1250" isPdfEmbedded="true"/>
    </textElement>
    <textFieldExpression><![CDATA[DATEFORMAT($P{timestamp},"dd.MM HH:mm")]]></textFieldExpression>
</textField>
Run Code Online (Sandbox Code Playgroud)

Maven依赖:

<dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports</artifactId>
    <version>5.6.0</version>
</dependency>
<dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports-functions</artifactId>
    <version>5.6.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

Java的:

private byte[] createPdf() {

    try {
        InputStream is = getClass().getResourceAsStream("MyReport.jasper");
        JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("timestamp", new Date());
        JRDataSource jrDataSource = new JRBeanCollectionDataSource(new Vector(), false);
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, jrDataSource);
        byte[] pdf = JasperExportManager.exportReportToPdf(jasperPrint);
        return pdf;
    } catch (JRException e) {
        throw new RuntimeException("Could not create PDF.", e);
    }
}
Run Code Online (Sandbox Code Playgroud)

原因是JRFontNotFoundException只有在fontName未安装属性中的字体时才会抛出:

fontName在任何运行时可用的JasperReports字体扩展中找不到用作报表模板中属性值的字体名称时,也不会在Java虚拟机可用的字体名称中找到异常.

如果pdfFontName没有安装属性中的字体(而不是使用任何其他安装的字体),有没有办法中止PDF的生成?

Pet*_*erg 5

您正在设定pdfFontNamefontName

pdfFontName是旧的方式,现在已经弃用以指示itext库应该使用什么字体,JRFontNotFoundException如果缺少字体,jasper-reports将不会抛出,而是itext会抛出一个被捕获并重新启动的异常JRRuntimeException.

在itext中,Helvetica作为afm文件包含在内,因此如果使用了这个,itext将不会抛出任何异常,但是如果你在jasper中指示另一种字体(在你的情况下不表示=默认字体),这并不能保证你的文本正确呈现 -报告.事实上,这是一个烂摊子,都pdfFontNamepfdEncoding被弃用.

如果没有安装属性pdfFontName中的字体,有没有办法中止PDF的生成?

不要使用pdfFontName,但如果你坚持(为了问题)然后也设置fontName="Helvetica",设置jasper-reports字体将引发JRFontNotFoundException如果没有找到.

正确的方法是只设置fontName,然后提供字体的扩展,在字体扩展你包括实际ttf,指示编码和是否应该被嵌入.

顺便说一句:我会使用编码Identity-H这是推荐用于较新的PDF标准,并使您能够混合不同的编码.