如何使用Apache pdfbox在PDF中生成多行 [英] How to generate multiple lines in PDF using Apache pdfbox

查看:31
本文介绍了如何使用Apache pdfbox在PDF中生成多行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Pdfbox 使用 Java 生成 PDF 文件.问题是当我在文档中添加长文本内容时,它无法正确显示.仅显示其中的一部分.这也是在一行中.

我希望文本在多行中.

我的代码如下:

PDPageContentStream pdfContent=new PDPageContentStream(pdfDocument, pdfPage, true, true);pdfContent.beginText();pdfContent.setFont(pdfFont, 11);pdfContent.moveTextPositionByAmount(30,750);pdfContent.drawString("我正在尝试创建一个包含大量文本内容的 PDF 文件.我正在使用 PDFBox");pdfContent.endText();

我的输出:

解决方案

添加到 Mark 的答案中,您可能想知道在哪里拆分长字符串.为此,您可以使用 PDFont 方法 getStringWidth.

把所有东西放在一起,你会得到这样的东西(根据 PDFBox 版本有细微差别):

PDFBox 1.8.x

PDDocument doc = null;尝试{doc = 新的 PDDocument();PDPage 页面 = 新的 PDPage();doc.addPage(页面);PDPageContentStream contentStream = new PDPageContentStream(doc, page);PDFont pdfFont = PDType1Font.HELVETICA;浮动字体大小 = 25;浮动领先 = 1.5f * 字体大小;PDRectangle mediabox = page.findMediaBox();浮动保证金 = 72;浮动宽度 = mediabox.getWidth() - 2*margin;float startX = mediabox.getLowerLeftX() + margin;float startY = mediabox.getUpperRightY() - 边距;String text = "我正在尝试创建一个包含大量文本内容的 PDF 文件.我正在使用 PDFBox";列表<字符串>行 = 新的 ArrayList();int lastSpace = -1;while (text.length() > 0){int spaceIndex = text.indexOf(' ', lastSpace + 1);if (spaceIndex <0)spaceIndex = text.length();String subString = text.substring(0, spaceIndex);浮点大小 = fontSize * pdfFont.getStringWidth(subString)/1000;System.out.printf("'%s' - %f of %f
", subString, size, width);如果(大小>宽度){如果 (lastSpace <0)lastSpace = 空间索引;subString = text.substring(0, lastSpace);行.添加(子字符串);text = text.substring(lastSpace).trim();System.out.printf("'%s' is line
", subString);lastSpace = -1;}else if (spaceIndex == text.length()){行.添加(文本);System.out.printf("'%s' is line
", text);文字=";}别的{lastSpace = 空间索引;}}contentStream.beginText();contentStream.setFont(pdfFont, fontSize);contentStream.moveTextPositionByAmount(startX, startY);for(字符串行:行){contentStream.drawString(line);contentStream.moveTextPositionByAmount(0, -leading);}contentStream.endText();contentStream.close();doc.save(break-long-string.pdf");}最后{如果(文档!= null){doc.close();}}

(BreakLongString.java 测试 testBreakString for PDFBox 1.8.x)

PDFBox 2.0.x

PDDocument doc = null;尝试{doc = 新的 PDDocument();PDPage 页面 = 新的 PDPage();doc.addPage(页面);PDPageContentStream contentStream = new PDPageContentStream(doc, page);PDFont pdfFont = PDType1Font.HELVETICA;浮动字体大小 = 25;浮动领先 = 1.5f * 字体大小;PDRectangle mediabox = page.getMediaBox();浮动保证金 = 72;浮动宽度 = mediabox.getWidth() - 2*margin;float startX = mediabox.getLowerLeftX() + margin;float startY = mediabox.getUpperRightY() - 边距;String text = "我正在尝试创建一个包含大量文本内容的 PDF 文件.我正在使用 PDFBox";列表<字符串>行 = 新的 ArrayList();int lastSpace = -1;while (text.length() > 0){int spaceIndex = text.indexOf(' ', lastSpace + 1);if (spaceIndex <0)spaceIndex = text.length();String subString = text.substring(0, spaceIndex);浮点大小 = fontSize * pdfFont.getStringWidth(subString)/1000;System.out.printf("'%s' - %f of %f
", subString, size, width);如果(大小>宽度){如果 (lastSpace <0)lastSpace = 空间索引;subString = text.substring(0, lastSpace);行.添加(子字符串);text = text.substring(lastSpace).trim();System.out.printf("'%s' is line
", subString);lastSpace = -1;}else if (spaceIndex == text.length()){行.添加(文本);System.out.printf("'%s' is line
", text);文字=";}别的{lastSpace = 空间索引;}}contentStream.beginText();contentStream.setFont(pdfFont, fontSize);contentStream.newLineAtOffset(startX, startY);for(字符串行:行){contentStream.showText(行);contentStream.newLineAtOffset(0, -leading);}contentStream.endText();contentStream.close();doc.save(新文件(RESULT_FOLDER,break-long-string.pdf"));}最后{如果(文档!= null){doc.close();}}

(BreakLongString.java 测试 testBreakString for PDFBox 2.0.x)

结果

这看起来符合预期.

当然还有许多改进需要做,但这应该说明如何去做.

添加无条件换行

在评论中 aleskv 问道:

<块引用>

当字符串中有 时,您可以添加换行符吗?

首先将字符串拆分为 ' ' 个字符,然后迭代拆分结果,可以轻松地将解决方案扩展为在换行符处无条件中断.

例如if 而不是上面的长字符串

String text = "我正在尝试创建一个包含大量文本内容的 PDF 文件.我正在使用 PDFBox";

你想用嵌入的换行符处理这个更长的字符串

String textNL = "我正在尝试创建一个包含大量文本内容的 PDF 文件.我正在使用 PDFBox.
此外,我在字符串中添加了一些换行符,在这些字符处也应该断行.
它应该像这样工作......";

你可以简单地替换

String text = "我正在尝试创建一个包含大量文本内容的 PDF 文件.我正在使用 PDFBox";列表<字符串>行 = 新的 ArrayList();int lastSpace = -1;while (text.length() > 0){[...]}

在上面的解决方案中

String textNL = "我正在尝试创建一个包含大量文本内容的 PDF 文件.我正在使用 PDFBox.
此外,我在字符串中添加了一些换行符,在这些字符处也应该断行.
它应该像这样工作......";列表<字符串>行 = 新的 ArrayList();for (String text : textNL.split("
")){int lastSpace = -1;while (text.length() > 0){[...]}}

(来自

I am using Pdfbox to generate PDF files using Java. The problem is that when i add long text contents in the document, it is not displayed properly. Only a part of it is displayed. That too in a single line.

I want text to be in multiple lines.

My code is given below:

PDPageContentStream pdfContent=new PDPageContentStream(pdfDocument, pdfPage, true, true);

pdfContent.beginText();
pdfContent.setFont(pdfFont, 11);
pdfContent.moveTextPositionByAmount(30,750);            
pdfContent.drawString("I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox");
pdfContent.endText();

My output:

解决方案

Adding to the answer of Mark you might want to know where to split your long string. You can use the PDFont method getStringWidth for that.

Putting everything together you get something like this (with minor differences depending on the PDFBox version):

PDFBox 1.8.x

PDDocument doc = null;
try
{
    doc = new PDDocument();
    PDPage page = new PDPage();
    doc.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(doc, page);

    PDFont pdfFont = PDType1Font.HELVETICA;
    float fontSize = 25;
    float leading = 1.5f * fontSize;

    PDRectangle mediabox = page.findMediaBox();
    float margin = 72;
    float width = mediabox.getWidth() - 2*margin;
    float startX = mediabox.getLowerLeftX() + margin;
    float startY = mediabox.getUpperRightY() - margin;

    String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 
    List<String> lines = new ArrayList<String>();
    int lastSpace = -1;
    while (text.length() > 0)
    {
        int spaceIndex = text.indexOf(' ', lastSpace + 1);
        if (spaceIndex < 0)
            spaceIndex = text.length();
        String subString = text.substring(0, spaceIndex);
        float size = fontSize * pdfFont.getStringWidth(subString) / 1000;
        System.out.printf("'%s' - %f of %f
", subString, size, width);
        if (size > width)
        {
            if (lastSpace < 0)
                lastSpace = spaceIndex;
            subString = text.substring(0, lastSpace);
            lines.add(subString);
            text = text.substring(lastSpace).trim();
            System.out.printf("'%s' is line
", subString);
            lastSpace = -1;
        }
        else if (spaceIndex == text.length())
        {
            lines.add(text);
            System.out.printf("'%s' is line
", text);
            text = "";
        }
        else
        {
            lastSpace = spaceIndex;
        }
    }
        
    contentStream.beginText();
    contentStream.setFont(pdfFont, fontSize);
    contentStream.moveTextPositionByAmount(startX, startY);            
    for (String line: lines)
    {
        contentStream.drawString(line);
        contentStream.moveTextPositionByAmount(0, -leading);
    }
    contentStream.endText(); 
    contentStream.close();

    doc.save("break-long-string.pdf");
}
finally
{
    if (doc != null)
    {
        doc.close();
    }
}

(BreakLongString.java test testBreakString for PDFBox 1.8.x)

PDFBox 2.0.x

PDDocument doc = null;
try
{
    doc = new PDDocument();
    PDPage page = new PDPage();
    doc.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(doc, page);

    PDFont pdfFont = PDType1Font.HELVETICA;
    float fontSize = 25;
    float leading = 1.5f * fontSize;

    PDRectangle mediabox = page.getMediaBox();
    float margin = 72;
    float width = mediabox.getWidth() - 2*margin;
    float startX = mediabox.getLowerLeftX() + margin;
    float startY = mediabox.getUpperRightY() - margin;

    String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 
    List<String> lines = new ArrayList<String>();
    int lastSpace = -1;
    while (text.length() > 0)
    {
        int spaceIndex = text.indexOf(' ', lastSpace + 1);
        if (spaceIndex < 0)
            spaceIndex = text.length();
        String subString = text.substring(0, spaceIndex);
        float size = fontSize * pdfFont.getStringWidth(subString) / 1000;
        System.out.printf("'%s' - %f of %f
", subString, size, width);
        if (size > width)
        {
            if (lastSpace < 0)
                lastSpace = spaceIndex;
            subString = text.substring(0, lastSpace);
            lines.add(subString);
            text = text.substring(lastSpace).trim();
            System.out.printf("'%s' is line
", subString);
            lastSpace = -1;
        }
        else if (spaceIndex == text.length())
        {
            lines.add(text);
            System.out.printf("'%s' is line
", text);
            text = "";
        }
        else
        {
            lastSpace = spaceIndex;
        }
    }

    contentStream.beginText();
    contentStream.setFont(pdfFont, fontSize);
    contentStream.newLineAtOffset(startX, startY);
    for (String line: lines)
    {
        contentStream.showText(line);
        contentStream.newLineAtOffset(0, -leading);
    }
    contentStream.endText(); 
    contentStream.close();

    doc.save(new File(RESULT_FOLDER, "break-long-string.pdf"));
}
finally
{
    if (doc != null)
    {
        doc.close();
    }
}

(BreakLongString.java test testBreakString for PDFBox 2.0.x)

The result

This looks as expected.

Of course there are numerous improvements to make but this should show how to do it.

Adding unconditional line breaks

In a comment aleskv asked:

could you add line breaks when there are in the string?

One can easily extend the solution to unconditionally break at newline characters by first splitting the string at ' ' characters and then iterating over the split result.

E.g. if instead of the long string from above

String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 

you want to process this even longer string with embedded new line characters

String textNL = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox.
Furthermore, I have added some newline characters to the string at which lines also shall be broken.
It should work alright like this...";

you can simply replace

String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 
List<String> lines = new ArrayList<String>();
int lastSpace = -1;
while (text.length() > 0)
{
    [...]
}

in the solutions above by

String textNL = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox.
Furthermore, I have added some newline characters to the string at which lines also shall be broken.
It should work alright like this..."; 
List<String> lines = new ArrayList<String>();
for (String text : textNL.split("
"))
{
    int lastSpace = -1;
    while (text.length() > 0)
    {
        [...]
    }
}

(from BreakLongString.java test testBreakStringNL)

The result:

这篇关于如何使用Apache pdfbox在PDF中生成多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆