В общем, вам следует посоветовать реализовать свой собственный TableRenderer и обрабатывать макет самостоятельно. Однако, поскольку алгоритм разметки TableRenderer действительно очень сложен, я советую использовать вместо него следующий CellRenderer:
class CustomCellRenderer extends CellRenderer {
public CustomCellRenderer(Cell modelElement) {
super(modelElement);
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
if (LayoutResult.FULL != result.getStatus()) {
result.setStatus(LayoutResult.NOTHING);
result.setSplitRenderer(null);
result.setOverflowRenderer(this);
}
return result;
}
@Override
public IRenderer getNextRenderer() {
return new CustomCellRenderer((Cell)getModelElement());
}
}
Как вы можете видеть здесь, если ячейка не помещается на странице, CustomCellRenderer гарантирует, что результатом макета будет НИЧЕГО (ничто не может быть размещено в текущей области), а не ЧАСТИЧНО (ячейка может быть разделена).
В своем вопросе вы упомянули пример HeaderFooter2. Это тот же пример, портированный на iText7: https://github.com/itext/i7js-book/blob/develop/src/test/java/com/itextpdf/samples/book/part1/chapter04/Listing_04_19_HeaderFooter2.java
Вот как вы можете обновить его с помощью CustomCellRendrer:
for (Screening screening : screenings) {
movie = screening.getMovie();
cell = new Cell().add(new Paragraph(screening.getLocation()));
cell.setNextRenderer(new CustomCellRenderer(cell));
table.addCell(cell);
cell = new Cell().add(new Paragraph(String.format("%1$tH:%1$tM", screening.getTime())));
cell.setNextRenderer(new CustomCellRenderer(cell));
table.addCell(cell);
cell = new Cell().add(new Paragraph(String.format("%d '", movie.getDuration())));
cell.setNextRenderer(new CustomCellRenderer(cell));
table.addCell(cell);
cell = new Cell().add(new Paragraph(movie.getMovieTitle()));
cell.setNextRenderer(new CustomCellRenderer(cell));
table.addCell(cell);
cell = new Cell().add(new Paragraph(String.valueOf(movie.getYear())));
cell.setNextRenderer(new CustomCellRenderer(cell));
table.addCell(cell);
cell = new Cell();
cell.setNextRenderer(new CustomCellRenderer(cell));
cell.add(PojoToElementFactory.getDirectorList(movie));
table.addCell(cell);
cell = new Cell();
cell.setNextRenderer(new CustomCellRenderer(cell));
cell.add(PojoToElementFactory.getCountryList(movie));
table.addCell(cell);
}
Как видите, я установил рендерер для ячеек методом setNextRenderer
. (Обратите внимание, что только пользовательские ячейки «body» должны обрабатываться вашим пользовательским средством визуализации, поскольку мы предполагаем, что верхний и нижний колонтитулы не будут разделяться).
Теперь давайте посмотрим на результаты.
Вот как сплит был обработан раньше:
И вот как это обрабатывается сейчас:
Код, который я использовал в ответе, написан на Java, но поскольку API-интерфейс iText в C # такой же, как и в Java, у вас не должно возникнуть проблем с его портированием.