为什么 Linux 下的 PDF 文本会被截断?

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

我尝试在 Jasper Reports 中格式化日期,它适用于 Windows,但不适用于 Linux。对于 Linux,生成的文本会被截断。

代码:

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)

爪哇:

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)

结果:

Windows 的结果:

视窗

Linux 的结果:

Linux

PDF 属性:

生成的两个 PDF 文件在 Windows 版 Acrobat Reader 中具有相同的字体属性:

PDF 属性

如您所见,字体未嵌入。jasperreports-fonts(如果我添加依赖项并删除属性pdfFontNamepdfEncoding和,第二个字体“Helvetica”就会消失isPdfEmbedded)。

研究:

我读:

解决方案似乎是嵌入字体,但不起作用。

我使用字体“Helvetica”,它是默认字体之一,这就是原因,请参阅维基百科

这些字体或具有相同规格的合适替代字体必须始终在所有 PDF 阅读器中可用,因此无需嵌入 PDF 中

/sf/answers/1914157241/

如果您在 iText 中使用这些字体,iText 将忽略嵌入的参数,因为可以安全地假设 Adob​​e Reader 和其他查看器可以正确呈现这些字体。

问题:

为什么相同的字体在 Windows 和 Linux 上有不同的宽度?或者为什么文本截断和/或换行不同?

Pet*_*erg 4

为了正确计算字体规格,字体需要可供 java 虚拟机使用。

请参阅这个历史问题:Font is not available to the JVM with Jasper Reports,它显示了针对已启动的旧错误的各种解决方案

然而,jasper-reports 的正确解决方案是使用 font-extensions

如果您使用分布式jasperreports-font.jar它包含这些字体:

DejaVu Sans
DejaVu Serif
DejaVu Sans Mono

您需要在字体名称示例中使用其中之一fontName="DejaVu Sans",没有自动映射到其他字体,jar 物理上只包含这些字体.ttf,没有其他字体(打开 jar 并验证不同版本的 jasper-reports)。

因此,只有安装在 PC 上或包含在 font-extension 中的字体可用于 JVM。

如果您需要其他字体,最好的解决方案是生成您自己的字体扩展,包括有效的.ttf字体,这可以在 IDE 中完成。