I want to remove setFixedLeading
at the first line on each page (100+)
I read a bit text(more 100 page with help while). And I set padding and margin to 0 but I still have top indent. Why? Help me pls? How delete it?
public static final String DEST = "PDF.pdf"; public static void main(String[] args) throws FileNotFoundException { PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST)); Document doc = new Document(pdfDoc); doc.setMargins(0,0,0,0); for (int i = 0; i <20 ; i++) { Paragraph element = new Paragraph("p " + i); element.setPadding(0); element.setMargin(0); element.setFixedLeading(55); doc.add(element); } doc.close(); }
PDF file: https://pdfhost.io/v/Byt9LHJcy_PDFpdf.pdf
Advertisement
Answer
At the time of element creation you don’t know the page it will end up on nor its resultant position. I don’t think there is a property that allows you to configure the behavior depending on whether it’s the top element on a page (such property would be too custom and tied to a specific workflow).
Fortunately, the layout mechanism is quite flexible and you can implement the desired behavior in a couple of lines of code.
First off, let’s not use setFixedLeading
and set the top margin for all paragraphs instead:
Document doc = new Document(pdfDocument); doc.setMargins(0, 0, 0, 0); for (int i = 0; i < 20; i++) { Paragraph element = new Paragraph("p " + i); element.setPadding(0); element.setMargin(0); element.setMarginTop(50); doc.add(element); } doc.close();
This does not pretty much change anything in the visual result – it’s just another way of doing things.
Now, we need a custom renderer to tweak the behavior of a paragraph if it is rendered at the top of the page. We are going to override layout
method and check if the area we are given is located at the top of the page – and if so, we will not apply the top margin:
private static class CustomParagraphRenderer extends ParagraphRenderer { Document document; public CustomParagraphRenderer(Paragraph modelElement, Document document) { super(modelElement); this.document = document; } @Override public IRenderer getNextRenderer() { return new ParagraphRenderer((Paragraph) modelElement); } @Override public LayoutResult layout(LayoutContext layoutContext) { if (layoutContext.getArea().getBBox().getTop() == document.getPdfDocument().getDefaultPageSize().getHeight()) { ((Paragraph)getModelElement()).setMarginTop(0); } return super.layout(layoutContext); } }
Now the only thing we need to do is to set the custom renderer instance to each paragraph in the loop:
element.setNextRenderer(new CustomParagraphRenderer(element, doc));
Visual result: