Может кто-нибудь объяснить, пожалуйста, порядок рисования на холсте iTexts?
Я пытаюсь нарисовать несколько вложенных таблиц в iText, так как я думал, что это будет самый простой способ разместить все.
Так что у меня есть несколько таблиц внутри другой таблицы, которые имеют цвет фона и / или обводки (через PdfPCellEvents). К сожалению, штрихи внешнего стола перекрывают фон внутреннего стола. Я предполагаю, что это происходит из-за неправильного порядка применения или некоторого неправильного набора saveState
или же restoreState
в моих PdfPCellEvents.
Может ли кто-нибудь объяснить правильное использование saveState
а также restoreState
и дайте мне подсказку, как правильно наносить фоны и штрихи?
Вот мой код для добавления ячейки с полосатым фоном:
PdfPCell scaleBackground = new PdfPCell();
scaleBackground.setBorder(Rectangle.NO_BORDER);
scaleBackground.setVerticalAlignment(Element.ALIGN_TOP);
scaleBackground.setCellEvent(new StripedScaleBackground(max, scaleHeight));
Метод cellLayout StripedScaleBackground:
public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
float llx = rect.getLeft();
float lly = rect.getBottom();
float urx = rect.getRight();
float ury = rect.getTop();
// Light scale lines with padding from left
canvas.setLineWidth(Constants.BORDER_WIDTH_THIN);
canvas.setColorStroke(Colors.LIGHT_GRAY);
float paddingLeft = 22f;
for (int i = 0; i <= this.maxValue; i++)
{
canvas.moveTo(llx + paddingLeft, lly + (this.scaleHeight * (i + 1)));
canvas.lineTo(urx, lly + (this.scaleHeight * (i + 1)));
}
// Vertical line
canvas.moveTo(llx + (((urx - llx) + paddingLeft) / 2), ury);
canvas.lineTo(llx + (((urx - llx) + paddingLeft) / 2), lly);
canvas.stroke();
// Fat line left and right
canvas.moveTo(llx, ury);
canvas.lineTo(llx, lly);
canvas.moveTo(urx, ury);
canvas.lineTo(urx, lly);
canvas.setLineWidth(0.8f);
canvas.setColorStroke(Colors.MEDIUM_GRAY);
canvas.stroke();
canvas.saveState();
canvas.restoreState();
}
Гистограммы представляют собой таблицы, где в каждой ячейке есть событие ячейки для градиента и границы. Гистограммы добавляются в scaleBackground
PdfPCell первого куска кода и имеет следующие PdfPCellEvents (пример черной части диаграммы):
public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
PdfContentByte backgroundCanvas = canvases[PdfPTable.BACKGROUNDCANVAS];
float llx = rect.getLeft();
float lly = rect.getBottom();
float urx = rect.getRight();
float ury = rect.getTop();
// Draw background
// Define shading with direction and color
PdfShading shading = PdfShading.simpleAxial(this.writer,
llx, ury,
llx, lly,
Colors.BAR_CHART_BLACK_LIGHT, Colors.BAR_CHART_BLACK_DARK);
PdfShadingPattern pattern = new PdfShadingPattern(shading);
backgroundCanvas.setShadingFill(pattern);
// Draw shape with defined shading
backgroundCanvas.moveTo(llx, ury);
backgroundCanvas.lineTo(llx, lly);
backgroundCanvas.lineTo(urx, lly);
backgroundCanvas.lineTo(urx, ury);
backgroundCanvas.lineTo(llx, ury);
backgroundCanvas.fill();
backgroundCanvas.saveState();
backgroundCanvas.restoreState();
// Draw border
PdfContentByte lineCanvas = canvases[PdfPTable.LINECANVAS];
float lineWidth = Constants.BORDER_WIDTH_THIN;
lineCanvas.setLineWidth(lineWidth);
lineCanvas.moveTo(llx, ury - lineWidth);
lineCanvas.lineTo(llx, lly);
lineCanvas.lineTo(urx, lly);
lineCanvas.lineTo(urx, ury - lineWidth);
lineCanvas.setColorStroke(BaseColor.BLACK);
lineCanvas.stroke();
lineCanvas.saveState();
lineCanvas.restoreState();
}
1 ответ
Это порядок различных прямых слоев контента:
PdfPtable.BASECANVAS
- Все, что находится здесь, будет под столом.PdfPtable.BACKGROUNDCANVAS
—Это слой, где нарисованы фоны.PdfPtable.LINECANVAS
—Это слой, где нарисованы линии.PdfPtable.TEXTCANVAS
—Это слой, куда идет текст. Все, что здесь размещено, покроет стол.
Это было взято из книги "iText в действии - второе издание".
Вы также спрашиваете о saveState()
а также restoreState()
, Это объясняется в главе 2 учебника по iText 7:
Сначала мы сохраняем текущее графическое состояние с помощью
saveState()
метод, затем мы меняем состояние и рисуем любые линии или фигуры, которые мы хотим нарисовать, наконец, мы используемrestoreState()
метод возврата к исходному графическому состоянию. Все изменения, которые мы применили послеsaveState()
будет отменен Это особенно интересно, если вы меняете несколько значений (ширина линии, цвет,...) или когда трудно рассчитать обратное изменение (возврат к исходной системе координат).
Ваш код был слишком длинным для меня, чтобы проверить, но я очень сомневаюсь, что saveState()
/restoreState()
будет причиной вашей проблемы.
Я бы постарался максимально избежать вложенности таблиц. Обычно гораздо проще (и эффективнее) использовать colspan и rowspan.
Если это не решит вашу проблему, пожалуйста, объясните вашу проблему в одном предложении.