Прямоугольный блок верхнего и нижнего колонтитулов на каждой странице PDF с использованием OpenPDF

#pdf #pdf-generation #openpdf

#PDF #pdf-генерация #openpdf

Вопрос:

Я создаю отчет о счете-фактуре в формате PDF с использованием OpenPDF. В PDF мне нужно установить прямоугольный блок для верхнего / нижнего колонтитулов на каждой странице. Я использовал HeaderFooter класс для добавления верхнего / нижнего колонтитулов на каждую страницу, но это работает только для Phrase .

 HeaderFooter header = new HeaderFooter(new Phrase("This is a Header."), false);
 

Есть ли какой-либо способ установить прямоугольный блок с высотой и шириной для верхнего / нижнего колонтитула с помощью HeaderFooter class?

Это то, что я ожидаю на каждой странице:

ожидаемый результат

Ответ №1:

Вы можете сделать это, создав свой пользовательский PdfPageEvent интерфейс, в который вы добавляете элементы всякий раз, когда новая страница завершена (onEndPage-событие). Самый простой способ сделать это — расширить PdfPageEventHelper в отдельном классе или в анонимном классе. Сначала определите и оформите свои прямоугольники. Во-вторых, добавьте их на страницу, используя PdfWriter внутренний обратный вызов.

Вот демонстрация, показывающая, как это сделать:

 Document document = new Document(PageSize.A4, 40, 40, 200, 200);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));

// footer
final Rectangle footer = new Rectangle(30, 30, PageSize.A4.getRight(30), 180);
footer.setBorder(Rectangle.BOX);
footer.setBorderColor(Color.BLACK);
footer.setBorderWidth(2);

// header
final Rectangle header = new Rectangle(footer);
header.setTop(PageSize.A4.getTop(30));
header.setBottom(PageSize.A4.getTop(180));

// content-box
final Rectangle box = new Rectangle(footer);
box.setTop(document.top());
box.setBottom(document.bottom());

// create and register page event to add the rectangles
writer.setPageEvent(new PdfPageEventHelper() {
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        PdfContentByte cb = writer.getDirectContent();
        cb.rectangle(header);
        cb.rectangle(footer);
        cb.rectangle(box);
    }
});

document.open();
document.add(new Paragraph(LOREM_IPSUM)); // just some constant filler text
document.close();
 

Результат выглядит следующим образом:

Результат

Комментарии:

1. Всего два примечания: разработчики iText рекомендовали не добавлять содержимое в onStartPage , только в onEndPage и никогда в Document , но всегда в PdfWriter . Добавление Document в onStartPage может в ситуациях граничного согласования вызывать нежелательные артефакты.

2. @mkl Я отредактировал свой ответ, чтобы добавить содержимое в onEndPage , используя PdfWriter , как вы предложили. Спасибо, что ознакомили меня с этими фактами, я действительно ценю это. Возможно, эти заметки можно было бы добавить в JavaDoc OpenPDF для дальнейшего использования.