Если ваш контент находится в таблице и вы хотите нарисовать вокруг него прямоугольник, наиболее простой способ - использовать границу таблицы. Это избавляет от необходимости рисовать дополнительный прямоугольник.
Если требуется рисование прямоугольника отдельно, вы можете просто добавить содержимое и получить результирующее положение по вертикали (writer.getVerticalPosition(false)
). Затем нарисуйте прямоугольник на основе вертикального положения до и после добавления содержимого.
Тем не менее общая c проблема определения области, необходимой для визуализации фрагмента содержимого, представляет интерес. Поэтому я отвечу в контексте таблицы, как определено в вопросе, хотя, вероятно, это не самый полезный подход. Его можно применять для других типов контента и вариантов использования.
Прежде всего, в PDF координаты увеличиваются слева направо и от снизу вверх . Конструктор Rectangle
, который вы используете, - Rectangle(final float lowerleftx, final float lowerlefty, final float upperrightx, final float upperrighty)
. Таким образом, lowerlefty
должно быть меньше, чем upperrighty
. Вы также можете проигнорировать это, определить Rectangle
«вверх ногами» и вызвать Rectangle.normalize()
.
Чтобы определить вертикальное пространство, необходимое для рендеринга контента, вы можете запустить ColumnText
в режиме моделирования. Он будет выполнять всю логику рендеринга c без фактической записи содержимого в документ PDF. Затем вы можете использовать информацию из этого прогона моделирования для настройки фактического рендеринга на втором этапе.
PdfContentByte cb = writer.getDirectContent();
// the initial rectangle defines the max size of the content
Rectangle rect = new Rectangle(10, document.getPageSize().getBottom() + 50,
document.getPageSize().getWidth() - 2 * 10, document.getPageSize().getTop() - 50);
// flip the rectangle if top and bottom were switched
rect.normalize();
ColumnText ct = new ColumnText(cb);
ct.setSimpleColumn(rect);
ct.addElement(createTable1(auditBundle, context));
// do a simulation run
int result = ct.go(true);
// assume the content fits in the initial rectangle
if (result == ColumnText.NO_MORE_TEXT) {
// the bottom of the simulated content
float verticalpos = ct.getYLine();
// redefine the rectangle based on the simulation
rect = new Rectangle(10, verticalpos, document.getPageSize().getWidth() - 2 * 10,
document.getPageSize().getTop() - 50);
ct.setSimpleColumn(rect);
// the original content was consumed in the simulation, so add it again
ct.addElement(createTable1(auditBundle, context));
// render again
ct.go(false);
// draw the rectangle
rect.setBorder(Rectangle.BOX);
rect.setBorderWidth(1);
rect.setBorderColor(BaseColor.RED);
cb.rectangle(rect);
}
Дальнейшие изменения исходного кода:
- Удалена фиксированная высота ячейки таблицы, поэтому рост и сжатие прямоугольника можно продемонстрировать более четко: удалено
table.getDefaultCell().setFixedHeight(112f)
- Удалена граница таблицы и изменен цвет прямоугольника на красный, чтобы прямоугольник отображался более четко.
Результат с коротким текстом:
Результат с длинным текстом: