Reputation: 413
I'm working with a label printer which prints my pdf file. I create the file like this:
public static Document createPDF() {
float pageWidth = 176f;
float pageHeight = 200f;
Rectangle pageSize = new Rectangle(pageWidth, pageHeight);
Document document = new Document(pageSize);
document.setMargins(5, 5, 1, 0);
String file = MainActivity.FILE_URI;
try {
PdfWriter.getInstance(document,new FileOutputStream(file));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (DocumentException e1) {
e1.printStackTrace();
}
return document;
}
Then I add some paragraphs to it. The paragraphs have variabel length. When I exceed the length of the page IText adds another page. The pages are 62 x 75 mm.
I want to change the length based on the amount of text so I don't waste paper. I tried this:
try {
PdfReader reader = new PdfReader(MainActivity.FILE_URI);
while (reader.getNumberOfPages() > 1) {
float pageHeight = document.getPageSize().getHeight();
float pageWidth = document.getPageSize().getWidth();
pageHeight += 50f;
document.setPageSize(new Rectangle(pageWidth, pageHeight));
}
} catch (IOException e) {
e.printStackTrace();
}
But it's not working. The pages aren't getting longer so the number of pages stays the same and causes a loop.
Anyone knows a solution?
Upvotes: 0
Views: 5564
Reputation: 95918
Essentially you need to first draw on a very long page, longer than any plausible input to your use case, and then cut off the lower, empty parts.
This means that you have to start by setting your pageHeight
value accordingly. A safe value is
float pageHeight = 14400f;
The result you get now is a PDF document with one extremely long page, more than 5m in length.
This page has to be shortened to match the contents. This can be done in a second pass like this (I use the pageSize
rectangle you have already defined; INTERMEDIATE points to the PDF you generated in the first pass):
PdfReader reader = new PdfReader(INTERMEDIATE);
PdfStamper stamper = new PdfStamper(reader, FINAL_RESULT);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
TextMarginFinder finder = parser.processContent(1, new TextMarginFinder());
PdfDictionary page = reader.getPageN(1);
page.put(PdfName.CROPBOX, new PdfArray(new float[]{pageSize.getLeft(), finder.getLly(), pageSize.getRight(), pageSize.getTop()}));
stamper.markUsed(page);
stamper.close();
reader.close();
Depending on your document data you can keep the intermediary PDF in memory by using a ByteArrayOutputStream
for your PdfWriter
, retrieving the intermdeiate PDF as byte[]
after document.close()
, and feeding that byte[]
into the PdfReader
in the second step.
Upvotes: 2