PDFBOX相同流,带有粗体和普通文本

时间:2014-02-04 19:12:49

标签: java fonts pdfbox

我一直在使用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;
}

感谢您的建议

2 个答案:

答案 0 :(得分:10)

关于你的问题

  

我想做点什么

     

喜欢:这个(在同一行上有粗体和普通文字)。

     

我一直在使用溪流:

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

  • 人为加粗:使用文字渲染模式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();

结果:

Screenshot of StyledTexts.pdf

关于提供的代码

您拥有的代码不会创建100%有效的PDF:它设置字体

stream.setFont(PDType1Font.TIMES_BOLD, 10)

在文本对象之外

stream.beginText();
...
stream.endText();

这是无效的PDF;但很多PDF观众都接受了它。

此外,它真的很难读(隐藏的名字,奇怪的架构)。

答案 1 :(得分:0)

作为@mkl答案的编辑

我正在使用PDFBox 2.0.17,在PDPa​​geContentStream上,您具有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");

相匹配

希望这会有所帮助。