pdfBox为pdf添加不同的行

时间:2016-04-19 08:23:15

标签: java pdf pdfbox

我正在研究生成pdf文档。目前我正在尝试不同的方法。我想在pdf文档中获得多行。使用HelloWorld代码示例,我提出了......

package org.apache.pdfbox.examples.pdmodel;

import java.io.IOException;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

import org.apache.pdfbox.pdmodel.PDPageContentStream;

import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

/**
 * Creates a "Hello World" PDF using the built-in Helvetica font.
 *
 * The example is taken from the PDF file format specification.
 */
public final class HelloWorld
{
    private HelloWorld()
    {
    }

    public static void main(String[] args) throws IOException
    {

        String filename = "line.pdf";
        String message = "line";

        PDDocument doc = new PDDocument();
        try
        {
            PDPage page = new PDPage();
            doc.addPage(page);

            PDFont font = PDType1Font.HELVETICA_BOLD;

            PDPageContentStream contents = new PDPageContentStream(doc, page);
            contents.beginText();
            contents.setFont(font, 12);
            // Loop to create 25 lines of text
            for (int y = 0; y< 25; y++) {
                int ty = 700 + y * 15;
                contents.newLineAtOffset(100, ty);
                //contents.newLineAtOffset(125, ty);
                //contents.showText(Integer.toString(i));
                contents.showText(message + " " + Integer.toString(i));
                System.out.println(message + " " + Integer.toString(i));
            }
            contents.endText();
            contents.close();

            doc.save(filename);
        }
        finally
        {
            doc.close();
            System.out.println("HelloWorld finished after 'doc.close()'.");
        }
    }
}

但是看看我生成的文档,我只看到“第0行”一次,没有其他行。我做错了什么?

PDF document with only one line

2 个答案:

答案 0 :(得分:7)

您的问题是您认为PDPageContentStream.newLineAtOffset使用绝对坐标。情况并非如此,它使用相对坐标,参见JavaDocs:

/**
 * The Td operator.
 * Move to the start of the next line, offset from the start of the current line by (tx, ty).
 *
 * @param tx The x translation.
 * @param ty The y translation.
 * @throws IOException If there is an error writing to the stream.
 * @throws IllegalStateException If the method was not allowed to be called at this time.
 */
public void newLineAtOffset(float tx, float ty) throws IOException

所以你的附加行远离可见页面区域。

因此,您可能想要这样的事情:

...
contents.beginText();
contents.setFont(font, 12);
contents.newLineAtOffset(100, 700);
// Loop to create 25 lines of text
for (int i = 0; i < 25; i++) {
    contents.showText(message + " " + Integer.toString(i));
    System.out.println(message + " " + Integer.toString(i));
    contents.newLineAtOffset(0, -15);
}
contents.endText();
...

这里从100,700开始,每行向下移动15。

答案 1 :(得分:0)

除了mkl的答案,您还可以为每一行创建一个新的文本操作。这样做可以让你使用绝对坐标。

public static void showTextRightAligned(PDPageContentStream contentStream, PDType1Font font, int fontsize, float rightX, float topY, String text) throws IOException
{
    float textWidth = fontsize * font.getStringWidth(text) / 1000;
    float leftX = rightX - textWidth;
    contentStream.beginText();
    contentStream.newLineAtOffset(leftX, topY);
    contentStream.showText(text);
    contentStream.endText();
}

您是否需要这个取决于您的用例 例如,我想写一些右对齐的文本。在这种情况下,使用绝对位置更容易,所以我创建了一个这样的辅助方法:

$scope.hexGrid = [];
$scope.hexGrid[0] = [{name:'Test'},{name: 'Test1'}];
$scope.hexGrid[1] = [{name: 'Xyz'}, {name: 'Xyz1'}];