【问题标题】:PDFBOX Same Stream with bold and normal textPDFBOX 相同的流,带有粗体和普通文本
【发布时间】:2014-02-28 22:37:08
【问题描述】:

好吧,我一直在使用 PDFBox,但我仍然完全不明白,但我已经阅读了文档、使用字体和其他一些地方,但我已经找到了如何从PDF 和它的风格,但我正在创建它,而不是阅读它。

我正在尝试做点什么

点赞:这个(粗体和普通文本在同一行)。

我一直在使用流:

不确定这是否是帮助我所需的所有代码,因为我刚加入这个项目,但它在我加入时就开始了。

如果您能帮助我实现此代码,或者帮助我提供可以阅读解决方案的想法或来源,我将感谢大家。

我把我的代码留在这里:

public void rCovernoteFooter(PDPageContentStream stream , float x, float y) throws IOException {
    y = y-20;
    String currentDate = df1.format(new Date());
    String[] issues = constants.issued().split("/");
    String issued = issues[0] + currentDate + issues[1];
    y = rText(stream, x, y, 90, 0, 10, issued, null);
    stream.setFont(PDType1Font.TIMES_ROMAN, 8);
    y = rText(stream, x, y - 50, 117, 0, 10, constants.terms(), null);
}

public float rText(PDPageContentStream cStream, float x, float y, int col1, int col2, int spc, String data1, String data2) throws IOException {
    float y1 = 0f;
    float y2 = 0f;
    if (data2 == null) {
        y = iterate(data1, col1, x, y, spc, cStream);
    } else {
        y1 = iterate(data1, col1, x, y, spc, cStream);
        y2 = iterate(data2, col2, x + 125, y, spc,  cStream);
        if (y1 >= y2) {
        return y2;
        } else {
        return y1;
        }
    }
    return y;
}

private float iterate(String text, int len, float x, float y, int space, PDPageContentStream stream) throws IOException {
    int rowHeight = 0;
    List<String> wordList = Lists.newArrayList();
    wordList = wordLines(text, len);

    stream.setFont(PDType1Font.TIMES_BOLD, 10);
    for (String word : wordList) {
        stream.beginText();
        stream.moveTextPositionByAmount(x, y - rowHeight);
        stream.drawString(word);
        stream.endText();
        if (wordList.size() != 1)
        rowHeight = rowHeight + 10;
    }
    if (rowHeight >= space) {
        y = y - (rowHeight + 10);
    } else {
        y = y - space;
        }
    return y;
}

感谢您的建议

【问题讨论】:

    标签: java fonts pdfbox


    【解决方案1】:

    我正在尝试做点什么

    赞:这个(粗体和普通文本在同一行)。

    我一直在使用流:

    创建粗体(或其他样式)文本的最佳方法是使用为该变体明确创建的字体变体。但是,如果没有此类字体可用,则可以人为地模拟这些样式:

    • 人工加粗:使用文本渲染模式 2 不仅填充字母区域,还沿其轮廓绘制一条线
    • 人工勾勒:使用文本渲染模式 1 沿着字母的轮廓画一条线,而不是填充它
    • 人为斜体(实际上是倾斜的:更改文本矩阵以倾斜输出。

    在代码中:

    PDRectangle rec = new PDRectangle(220, 120);
    PDDocument document = null;
    document = new PDDocument();
    
    PDPage page = new PDPage(rec);
    document.addPage(page);
    
    PDPageContentStream content = new PDPageContentStream(document, page, true, true);
    
    content.beginText();
    content.moveTextPositionByAmount(7, 105);
    content.setFont(PDType1Font.HELVETICA, 12);
    content.drawString("Normal text and ");
    content.setFont(PDType1Font.HELVETICA_BOLD, 12);
    content.drawString("bold text");
    content.moveTextPositionByAmount(0, -25);
    content.setFont(PDType1Font.HELVETICA_OBLIQUE, 12);
    content.drawString("Italic text and ");
    content.setFont(PDType1Font.HELVETICA_BOLD_OBLIQUE, 12);
    content.drawString("bold italic text");
    content.endText();
    
    content.setLineWidth(.5f);
    
    content.beginText();
    content.moveTextPositionByAmount(7, 55);
    content.setFont(PDType1Font.HELVETICA, 12);
    content.drawString("Normal text and ");
    content.appendRawCommands("2 Tr\n");
    content.drawString("artificially bold text");
    content.appendRawCommands("0 Tr\n");
    content.moveTextPositionByAmount(0, -25);
    content.appendRawCommands("1 Tr\n");
    content.drawString("Artificially outlined text");
    content.appendRawCommands("0 Tr\n");
    content.setTextMatrix(1, 0, .2f, 1, 7, 5);
    content.drawString("Artificially italic text and ");
    content.appendRawCommands("2 Tr\n");
    content.drawString("bold italic text");
    content.appendRawCommands("0 Tr\n");
    content.endText();
    
    content.close();
    
    document.save("StyledTexts.pdf");
    document.close();
    

    结果:

    【讨论】:

    • 非常感谢,我会阅读并尝试实现它;顺便说一句,感谢您提供有关有效 PDF 的提示,我会记住的
    • 顺便说一句,你能教我“setTextMatrix(1, 0, .2f, 1, 7, 5);" 是怎么回事吗?作品?只是每个参数有什么变化,我一直在寻找它,但它只说:Tm 运算符。将文本矩阵设置为给定值。当前文本矩阵将替换为新文本矩阵。 a - 矩阵的 a 值。感谢和抱歉提出这样的菜鸟问题
    • 您可能想查看this answer 以及从那里引用的PDF 规范ISO 32000-1 的部分。
    • 这是一个非常有用的答案,但在最新版本的 PDFBox 中已弃用 appendRawCommands()。知道如何在不使用已弃用的 API 的情况下创建“人工粗体文本”吗?
    • :-( 好的,谢谢。现在 PDFBox 的理念似乎是摆脱附加原始命令而只使用 API - 只要 API 支持您想要的所有内容就可以了能够做到……
    【解决方案2】:

    作为@mkl 答案的编辑

    我使用的是 PDFBox 2.0.17,在 PDPageContentStream 上,您有 setRenderingMode 方法。

    为了模拟粗体文本,这里有一个小示例:

    try (PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, true, true)) {
        contentStream.beginText();
        contentStream.setFont(font, fontSize);
        contentStream.setRenderingMode(RenderingMode.FILL_STROKE);
        contentStream.setNonStrokingColor(color);
        contentStream.setTextMatrix(Matrix.getTranslateInstance(positionX, positionY));
        contentStream.showText(text);
        contentStream.endText();        
    }
    

    setRenderingMode 内码:

    public void setRenderingMode(RenderingMode rm) throws IOException
    {
        writeOperand(rm.intValue());
        writeOperator("Tr");
    }
    

    与之前的content.appendRawCommands("2 Tr\n");匹配

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2017-11-20
      • 2014-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多