如何在PDF页面中间确定正确的坐标?

时间:2016-09-25 16:16:50

标签: itext

我是iText的新手,我看了很多例子。我很难弄清楚的是矩形。在页面上

http://developers.itextpdf.com/examples/form-examples-itext5/multiline-fields

有许多示例具有Rectangle对象的硬编码值。例如:

Rectangle rect = new Rectangle(36, 770, 144, 806);

我的问题是我创建了一个Paragraph,我想在它下面添加一个可填写的文本输入框(多行)。我如何知道创建一个Rectangle对象的确切值,该对象可以很好地放在段落之后。段落文本的大小可以改变。所以我不能假设任何硬编码的值。

谢谢!

1 个答案:

答案 0 :(得分:2)

在iText 5中,iText在使用document.add()时会跟踪内容的坐标。你可以通过在绝对位置添加内容来自己控制(例如使用ColumnText),但这很难,因为那时你必须自己跟踪很多事情(例如:你必须介绍页面当内容到达页面底部时打破自己。)

如果您将坐标控件保留为iText,则可以使用页面事件访问这些坐标。

请看下面的示例,我们会在ParagraphonParagraph()方法中跟踪onParagraphEnd()的开头和结尾。这段代码示例不容易理解,但是如果我们想在文本块周围绘制一个矩形,它是获取iText 5中Paragraph坐标的唯一方法。正如您可以在该页面底部阅读的那样,iText 7可以更轻松地满足此要求。

如果您坚持使用iText 5,使用通用标签定义位置会更容易。请参阅GenericFields示例,其中我们使用导致字段的空Chunk。如果您想查看结果的屏幕截图,请参阅Add PdfPCell to Paragraph

在您的情况下,我要创建一个Paragraph,其中包含跨越不同行的Chunk,并且我会在onGenericTag()方法中添加该字段。页面事件。

假设我们有以下文本文件:jekyll_hyde.txt

我们如何将其转换为如下所示的PDF:

enter image description here

请注意添加到标题的蓝色边框以及每页底部的页码。在iText 5中,使用页面事件添加这些元素:

class MyPageEvents extends PdfPageEventHelper {

    protected float startpos = -1;
    protected boolean title = true;

    public void setTitle(boolean title) {
        this.title = title;
    }

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        Rectangle pagesize = document.getPageSize();
        ColumnText.showTextAligned(
            writer.getDirectContent(),
            Element.ALIGN_CENTER,
            new Phrase(String.valueOf(writer.getPageNumber())),
            (pagesize.getLeft() + pagesize.getRight()) / 2,
            pagesize.getBottom() + 15,
            0);
        if (startpos != -1)
            onParagraphEnd(writer, document,
                pagesize.getBottom(document.bottomMargin()));
        startpos = pagesize.getTop(document.topMargin());
    }

    @Override
    public void onParagraph(PdfWriter writer, Document document,
        float paragraphPosition) {
        startpos = paragraphPosition;
    }

    @Override
    public void onParagraphEnd(PdfWriter writer, Document document,
        float paragraphPosition) {
        if (!title) return;
        PdfContentByte canvas = writer.getDirectContentUnder();
        Rectangle pagesize = document.getPageSize();
        canvas.saveState();
        canvas.setColorStroke(BaseColor.BLUE);
        canvas.rectangle(
            pagesize.getLeft(document.leftMargin()),
            paragraphPosition - 3,
            pagesize.getWidth() - document.leftMargin() - document.rightMargin(),
            startpos - paragraphPosition);
        canvas.stroke();
        canvas.restoreState();
    }
}

我们可以使用以下代码将文本文件转换为PDF并将页面事件引入PdfWriter

public void createPdf(String dest)
throws DocumentException, IOException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
    MyPageEvents events = new MyPageEvents();
    writer.setPageEvent(events);
    document.open();
    BufferedReader br = new BufferedReader(new FileReader(TEXT));
    String line;
    Paragraph p;
    Font normal = new Font(FontFamily.TIMES_ROMAN, 12);
    Font bold = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD);
    boolean title = true;
    while ((line = br.readLine()) != null) {
        p = new Paragraph(line, title ? bold : normal);
        p.setAlignment(Element.ALIGN_JUSTIFIED);
        events.setTitle(title);
        document.add(p);
        title = line.isEmpty();
    }
    document.close();
}

来源:developers.itextpdf.com