Таблица iText внутри ColumnText не хранится вместе

Я использую iText 5.5.9. у меня есть PdfPTable что я показываю внутри ColumnText, ColumnText имеет маленький столбец и большой столбец.

Если таблица слишком велика для маленького столбца, она должна перейти ко второму, большему столбцу. Как я могу это сделать?

Я пытался с помощью table.setKeepTogether(true), но это не работает. Я также попробовал предложение с этой страницы ( http://itext.2136553.n4.nabble.com/PdfPTable-KeepTogether-and-ColumnText-td2141501.html), чтобы обернуть мою таблицу во вторую таблицу и использовать tableWrapper.setSplitRows(false), Но если я это сделаю, я больше не вижу таблицы.

Вот мой код:

public class PdfTest {
    private static String filename = "C:/Users/Development/Documents/pdf_test.pdf";

    public static void main(String[] args) {
        try {
            new PdfTest();
            File f = new File(filename);
            Desktop.getDesktop().open(f);
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }
    }

    public PdfTest() throws DocumentException, IOException {
        File file = new File(filename);
        OutputStream os = new FileOutputStream(file);

        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, os);

        document.open();

        PdfContentByte canvas = writer.getDirectContent();

        printPage1(document, canvas);

        document.newPage();

        printPage2(document, canvas);

        document.close();
        os.close();
    }

    private void printPage1(Document document, PdfContentByte canvas) throws DocumentException {
        int cols = 3;
        int rows = 15;

        PdfPTable table = new PdfPTable(cols);
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                table.addCell(new Phrase("Cell " + row + ", " + col));
            }
        }

        Paragraph paragraph = new Paragraph();
        paragraph.add(table);

        ColumnText columnText = new ColumnText(canvas);
        columnText.addElement(new Paragraph("This table should keep together!"));
        columnText.addElement(paragraph);

        int status = ColumnText.START_COLUMN;

        Rectangle docBounds = document.getPageSize();

        Rectangle bounds = new Rectangle(docBounds.getLeft(20), docBounds.getTop(20) - 200, docBounds.getRight(20), docBounds.getTop(20));
        bounds.setBorder(Rectangle.BOX);
        bounds.setBorderColor(BaseColor.BLACK);
        bounds.setBorderWidth(1);
        bounds.setBackgroundColor(new BaseColor(23, 142, 255, 20));

        canvas.rectangle(bounds);

        columnText.setSimpleColumn(bounds);

        status = columnText.go();

        if (ColumnText.hasMoreText(status)) {
            bounds = new Rectangle(docBounds.getLeft(20), docBounds.getBottom(20), docBounds.getRight(20), docBounds.getBottom(20) + 600);
            bounds.setBorder(Rectangle.BOX);
            bounds.setBorderColor(BaseColor.BLACK);
            bounds.setBorderWidth(1);
            bounds.setBackgroundColor(new BaseColor(255, 142, 23, 20));

            canvas.rectangle(bounds);

            columnText.setSimpleColumn(bounds);

            status = columnText.go();
        }
    }


    private void printPage2(Document document, PdfContentByte canvas) throws DocumentException {
        int cols = 3;
        int rows = 15;

        PdfPTable table = new PdfPTable(cols);
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                table.addCell(new Phrase("Cell " + row + ", " + col));
            }
        }

        PdfPTable tableWrapper = new PdfPTable(1);
        tableWrapper.addCell(table);
        tableWrapper.setSplitRows(false);

        Paragraph paragraph = new Paragraph();
        paragraph.add(tableWrapper);

        ColumnText columnText = new ColumnText(canvas);
        columnText.addElement(new Paragraph("This table should keep together!"));
        columnText.addElement(tableWrapper);

        int status = ColumnText.START_COLUMN;

        Rectangle docBounds = document.getPageSize();

        Rectangle bounds = new Rectangle(docBounds.getLeft(20), docBounds.getTop(20) - 200, docBounds.getRight(20), docBounds.getTop(20));
        bounds.setBorder(Rectangle.BOX);
        bounds.setBorderColor(BaseColor.BLACK);
        bounds.setBorderWidth(1);
        bounds.setBackgroundColor(new BaseColor(23, 142, 255, 20));

        canvas.rectangle(bounds);

        columnText.setSimpleColumn(bounds);

        status = columnText.go();

        if (ColumnText.hasMoreText(status)) {
            bounds = new Rectangle(docBounds.getLeft(20), docBounds.getBottom(20), docBounds.getRight(20), docBounds.getBottom(20) + 600);
            bounds.setBorder(Rectangle.BOX);
            bounds.setBorderColor(BaseColor.BLACK);
            bounds.setBorderWidth(1);
            bounds.setBackgroundColor(new BaseColor(255, 142, 23, 20));

            canvas.rectangle(bounds);

            columnText.setSimpleColumn(bounds);

            status = columnText.go();
        }
    }

}

РЕДАКТИРОВАТЬ: Теперь я понимаю, что я спрашиваю о решении, а не о самой проблеме. Так что я делаю шаг назад сюда.

Идея состоит в том, что в PDF есть дополнительное пространство для окна конверта на первой странице. Это окно будет отображать адрес. Это разделяет остальную часть (первой) страницы на две области выше и ниже окна конверта. Я пытался решить это с ColumnTexts. Я добавил заголовок, который аккуратно появляется над окном конверта. Затем я добавил таблицу. Эта таблица частично отображается над и под окном конверта. Таким образом, эти буквы могут содержать не только таблицы, и, возможно, несколько таблиц и абзацев.

1 ответ

Я хотел бы предложить использовать вспомогательный метод, который сначала пытается нарисовать Element в режиме симуляции, а затем действительно рисует его в первый прямоугольник, где он подходит.

Такой метод может выглядеть так:

Rectangle[] drawKeepTogether(Element element, PdfContentByte canvas, Rectangle... rectangles) throws DocumentException
{
    int i = 0;
    for (; i < rectangles.length; i++)
    {
        ColumnText columnText = new ColumnText(canvas);
        columnText.addElement(element);
        columnText.setSimpleColumn(rectangles[i]);
        int status = columnText.go(true);
        if (!ColumnText.hasMoreText(status))
            break;
    }

    if (i < rectangles.length)
    {
        Rectangle rectangle = rectangles[i];
        ColumnText columnText = new ColumnText(canvas);
        columnText.addElement(element);
        columnText.setSimpleColumn(rectangle);
        columnText.go(false);

        Rectangle[] remaining = new Rectangle[rectangles.length-i];
        System.arraycopy(rectangles, i, remaining, 0, remaining.length);
        remaining[0] = new Rectangle(rectangle.getLeft(), rectangle.getBottom(), rectangle.getRight(), columnText.getYLine());
        return remaining;
    }

    return new Rectangle[0];
}

(Метод TableKeepTogether.java drawKeepTogether )

Если используется так:

private void printPage3(Document document, PdfContentByte canvas) throws DocumentException {
    int cols = 3;
    int rows = 15;

    PdfPTable table = new PdfPTable(cols);
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < cols; col++) {
            table.addCell(new Phrase("Cell " + row + ", " + col));
        }
    }
    table.setSpacingBefore(5);

    Rectangle docBounds = document.getPageSize();
    Rectangle upper = new Rectangle(docBounds.getLeft(20), docBounds.getTop(20) - 200, docBounds.getRight(20), docBounds.getTop(20));
    upper.setBackgroundColor(new BaseColor(23, 142, 255, 20));
    Rectangle lower = new Rectangle(docBounds.getLeft(20), docBounds.getBottom(20), docBounds.getRight(20), docBounds.getBottom(20) + 600);
    lower.setBackgroundColor(new BaseColor(255, 142, 23, 20));
    Rectangle[] rectangles = new Rectangle[] { upper, lower };

    for (Rectangle bounds : rectangles)
    {
        bounds.setBorder(Rectangle.BOX);
        bounds.setBorderColor(BaseColor.BLACK);
        bounds.setBorderWidth(1);

        canvas.rectangle(bounds);
    }

    rectangles = drawKeepTogether(new Paragraph("This table should keep together!"), canvas, rectangles);
    rectangles = drawKeepTogether(table, canvas, rectangles);
}

(Метод TableKeepTogether.java printPage3 )

Страница, созданная этим методом, выглядит следующим образом:

keepTogetherTableInColumnText.pdf стр. 3

Другие вопросы по тегам