Java 为什么';如果PDF字体丢失,jasper报告会抛出JRFontNotFoundException吗?

Java 为什么';如果PDF字体丢失,jasper报告会抛出JRFontNotFoundException吗?,java,fonts,jasper-reports,pdf-generation,export-to-pdf,Java,Fonts,Jasper Reports,Pdf Generation,Export To Pdf,我读 我还以为Jasper Reports会在机器上没有安装字体时抛出错误 但是我的应用程序没有抛出一个错误,尽管我还没有在任何(Jaspersoft Studio、JasperReports、Adobe Acrobat Reader)机器上安装使用过的字体“Helvetica” JRXML: <parameter name="timestamp" class="java.util.Date"/> [...] <textField> <repor

我读

我还以为Jasper Reports会在机器上没有安装字体时抛出错误

但是我的应用程序没有抛出一个错误,尽管我还没有在任何(Jaspersoft Studio、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>
<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>
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);
    }
}

[...]
Maven依赖项:

<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>
<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>
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);
    }
}

net.sf.jasperreports
仅当未安装属性
fontName
中的字体时才会引发:

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


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

您正在设置
pdfFontName
fontName

pdfFontName
是一种旧方法,现在已弃用为了指示itext库应使用的字体,jasper reports不会抛出
JRFontNotFoundException
如果字体丢失,itext将抛出一个异常,该异常被捕获并作为
JRRuntimeException
重新启动

在itext中,Helvetica作为
afm
文件包含,因此,如果使用该文件,itext不会引发任何异常,但是,如果您在jasper报告中指示另一种字体(在您的情况下,不指示=默认字体),则这并不保证文本正确呈现。事实上,这是一个混乱的局面,
pdfFontName
pfdEncoding
都被弃用了

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

不要使用
pdfFontName
,但是如果您坚持(为了回答问题),那么也设置
fontName=“Helvetica”
,如果未找到,则设置jasper reports字体将引发
JRFontNotFoundException

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

顺便说一句:我会使用encoding Identity-H,这是最新的PDF标准的建议,并使您能够混合不同的编码