【问题标题】:Why is text truncated in PDF with Linux?为什么使用 Linux 截断 PDF 中的文本?
【发布时间】:2016-12-29 07:01:24
【问题描述】:

我尝试在 Jasper Reports 中格式化 Date,它适用于 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>

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>

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

结果:

Windows 的结果:

Linux 的结果:

PDF 属性:

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

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

研究:

我读到了:

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

我使用字体“Helvetica”,这是默认字体之一,这就是原因,请参阅Wikipedia

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

https://stackoverflow.com/a/27345103/5277820:

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

问题:

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

【问题讨论】:

  • 是的,您应该始终嵌入字体,以避免出现问题。请参阅帖子stackoverflow.com/a/26632606/5292302 中的 4 个错误(答案来自 itext 创始人),这不是最佳示例,但始终提供编码实践的想法,提供并嵌入字体

标签: java fonts jasper-reports pdf-generation export-to-pdf


【解决方案1】:

要正确计算字体度量,该字体需要对 java 虚拟机可用。

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

然而,jasper-reports 的正确解决方案是使用字体扩展

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

DejaVu Sans
DejaVu Serif
DejaVu Sans Mono

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

因此只有安装在电脑上或包含在字体扩展中的字体可用于 JVM。

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

【讨论】:

    【解决方案2】:

    永远不要假设客户端系统上可以使用特定字体 - 市场上只有几个桌面操作系统,提供少数西方语言的日子已经一去不复返了。稳定数十年。

    现在创建新字体变得更加容易,用户以自己的语言访问内容(使用特定语言的字体),行业每隔几年就会推出新的外形尺寸(使用新的虚荣字体),Unicode.org 发布新规范(需要彻底检查现有字体),因此不同系统上存在的实际字体差异很大。

    OSX 和 Windows 仍然在旧的“固定字体列表”模式下运行,但新进入者没有。

    对于 PDF,这意味着您必须在文档中嵌入字体。 对于网络而言,这意味着灵活的网站设计,不依赖于精确的像素字母尺寸。

    尝试使用像 Helvetica 或 Arial 这样的旧字体是一种病​​态的情况:要么客户端根本不会安装它,而是将其别名为具有不同字形指标的东西,或者它会有一个古老的版本,缺少自 ASCII 失宠以来添加的所有代码点,并且无法呈现现代国际文本。由于长窗口占主导地位,Arial 更有可能工作,但这种情况正在迅速消失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      • 2015-02-08
      • 1970-01-01
      相关资源
      最近更新 更多