문제 설명
종이 Itext7에서 첫 번째 줄과 마지막 줄 속성을 제거합니다. (Remove the first and last lines properties in the paper Itext7)
t.setRise(+‑) 가 필드 용지를 벗어나면 Text(setRise) 에서 속성을 제거해야 합니다.
PdfDocument pdfDoc = new PdfDocument(pdfWriter);
Document doc = new Document(pdfDoc, PageSize.A5);
doc.setMargins(0,0,0,36);
for (int i = 0; i <50 ; i++) {
Text t = new Text("hello " + i);
if(i ==0){
t.setTextRise(7);
}
if(i==31){
t.setTextRise(‑35);
}
Paragraph p = new Paragraph(t);
p.setNextRenderer(new ParagraphRen(p,doc));
p.setFixedLeading(fixedLeading);
doc.add(p);
}
doc.close();
}
class ParagraphRen extends ParagraphRenderer{
private float heightDoc;
private float marginTop;
private float marginBot;
public ParagraphRen(Paragraph modelElement, Document doc) {
super(modelElement);
this.heightDoc =doc.getPdfDocument().getDefaultPageSize().getHeight();
this.marginTop = doc.getTopMargin();
this.marginBot = doc.getBottomMargin();
}
@Override
public void drawChildren(DrawContext drawContext) {
super.drawChildren(drawContext);
Rectangle rect = this.getOccupiedAreaBBox();
List<IRenderer> childRenderers = this.getChildRenderers();
//check first line
if(rect.getTop()<=heightDoc‑ marginTop) {
for (IRenderer iRenderer : childRenderers) {
if (iRenderer.getModelElement().hasProperty(72)) {
Object property = iRenderer.getModelElement().getProperty(72);
float v = (Float) property + rect.getTop();
//check text more AreaPage
if(v >heightDoc){
iRenderer.getModelElement().deleteOwnProperty(72);
}
}
}
}
//check last line
if(rect.getBottom()‑marginBot‑rect.getHeight()*2<0){
for (IRenderer iRenderer : childRenderers) {
if (iRenderer.getModelElement().hasProperty(72)) {
Object property = iRenderer.getModelElement().getProperty(72);
//if setRise(‑..) more margin bottom setRise remove
if(rect.getBottom()‑marginBot‑rect.getHeight()+(Float) property<0)
iRenderer.getModelElement().deleteOwnProperty(72);
}
}
}
}
}
여기서 setRise가 있는 첫 번째 줄이 용지 영역보다 더 많은지 확인합니다. setRise 속성을 제거합니다.
그리고 serRise(‑35)가 있는 마지막 줄이 여백 하단보다 많으면 제거합니다.
하지만 작동하지 않습니다. 속성은 제거되지 않습니다.
참조 솔루션
방법 1:
Your problem is as follows: drawChildren
method gets called after rendering has been done. At this stage iText usually doesn't consider properties of any elements: it just places the element in its occupied area, which has been calculated before, at layout()
stage.
You can overcome it with layout emulation.
Let's add all your paragraphs to a div rather than directly to the document. Then emulate adding this div to the document:
LayoutResult result = div.createRendererSubTree().setParent(doc.getRenderer()).layout(new LayoutContext(new LayoutArea(0, PageSize.A5)));
In the snippet above I've tried to layout our div on a A5‑sized document.
Now you can consider the result of layout and change some elements, which will be then processed for real with Document#add
. For example, to get the 30th layouted paragraph one can use:
((DivRenderer)result.getSplitRenderer()).getChildRenderers().get(30);
Some more tips: split renderer represent the part of the content which iText can place on the area, overflow ‑ the content which overflows.
(by heavywar、Uladzimir Asipchuk)