I'm writing a pdf file with iText and I want the paragraphs divided across two different pages. How can I do this?
It is a lot easier to help if you could provide a more accurate example of the paragraphs and the document you are creating, but as far as I understand it is something like this:
Generate an ArrayList or other weapon of choise in making an iterable list of the paragraphs. Iterate through that list and call newPage() before adding content to page 2
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream([file]));
for (ArrayList<Paragraph> : theParagraph ) {
document.addElement(theParagraph)
document.newPage();
}
document.close();
This will automaticaly add new pages as content is added on the pdf-document, but with less controle over when the pagebreak occurs:
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream([file]));
document.open();
for(int i=0 ; i<100; i++){
document.add(new Paragraph("This is a very important message"));
}
document.close();
Related
I have a doubt about PDFDocuments. How can I copy a specific page of a PdfDocument object , to another PdfDocument object.
I've tried with the moveTo method , but It didn't worked , also Ive tried with copyPagesTo method , but I throws an Requested page is out of bounds (when I try to copy for example only one page , from 1 to 1).
Any hint?
List<PdfDocument> pdfDocuments = new ArrayList<>();
PdfDocument pdfWithMultiplePages = here I have a PDF with 3 pages.
for (int i = 0 ; i<pdfWithMultiplePages.getNumberOfPages() ; i++){
final ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
final PdfWriter pdfWriter = new PdfWriter(byteArrayOutputStream);
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
pdfDocument.copyPagesTo(i+1, i+1,pdfWithMultiplePages);
pdfWriter.close();
byteArrayOutputStream.close();
shippingLabels.add(shippingLabelSplitted);
}
I've tried also with this :
List<PdfDocument> pdfDocuments = new ArrayList<>();
PdfDocument pdfWithMultiplePages = here I have a PDF with 3 pages.
for (int i = 0 ; i<pdfWithMultiplePages.getNumberOfPages() ; i++){
final ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
final PdfWriter pdfWriter = new PdfWriter(byteArrayOutputStream);
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
pdfDocument.addPage(1,pdfWithMultiplePages.getPage(i+1));
pdfWriter.close();
byteArrayOutputStream.close();
shippingLabels.add(shippingLabelSplitted);
}
But it throws :
com.itextpdf.kernel.PdfException: Page com.itextpdf.kernel.pdf.PdfPage#6576eb4b cannot be added to document com.itextpdf.kernel.pdf.PdfDocument#286ef136, because it belongs to document com.itextpdf.kernel.pdf.PdfDocument#2c74aa66.
A page in a PDF has many relations to other objects in a PDF.
If you could add a page located in one document to another one, the page would reside in both documents. Thus, the page suddenly would have to have all those relations to objects in both documents. This obviously does not work, thus iText prevents this.
Instead you have to create a copy of the page(s) in question for which the relations are switched to documents in the target document.
For this task there are multiple method overloads of PdfDocument.copyPagesTo. Thus, these methods indeed are the ones to use.
Unfortunately you mistake source and target of the operation:
PdfDocument pdfWithMultiplePages = here I have a PDF with 3 pages.
....
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
pdfDocument.copyPagesTo(i+1, i+1,pdfWithMultiplePages);
This tries to copy page i+1 from pdfDocument to pdfWithMultiplePages. But you just created pdfDocument from scratch, so it does not have any pages yet. What you most probably want is:
pdfWithMultiplePages.copyPagesTo(i+1, i+1, pdfDocument);
I´m generating PDFs using iText and it works fine. But I need a way to import html styled informations from an existing PDF at some point.
I know i could just use the XMLWorker class to generate the text directly from html in my own document. But cause I´m not sure whether it actually supports all html features I´m looking to work around this.
Therefore a PDF is generated from html using XSLT. The content of this PDF then should be copied to my document.
There are two ways discribed in the book ("iText in Action").
One that parses the PDF and gets you the text (or other informations) from the document using PdfReaderContentParser and TextExtractionStrategy.
It looks like this:
PdfReader reader = new PdfReader(pdf);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
TextExtractionStrategy strategy;
for(int i=1;i<=reader.getNumberOfPages();i++){
strategy = parser.processContent(i, new LocationTextExtractionStrategy());
document.add(new Chunk(strategy.getResultantText()));
}
But this only prints plain text to the document. Obviously there are more ExtractionStrategys and maybe one of them does exactly what i want but i couldn´t find it yet.
The second way is to copy an itextpdf.text.Image of each side of the PDF to your document. This is obviously not a good idea, cause it will add the entire page to your document even if there is only one line of text in the existing PDF. Its done like this:
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
PdfReader reader = new PdfReader(pdf);
PdfImportedPage page;
for(int i=1;i<=reader.getNumberOfPages();i++){
page = writer.getImportedPage(reader,i);
document.add(Image.getInstance(page));
}
Like I said this copys all the empty lines at the end of the PDF aswell, but i need to continue my text immediatly after the last line of text.
If I could convert this itext.text.Image into a java.awt.BufferedImage I could use getSubImage(); and informations i can extract from the PDF to cut away all the empty lines. But i wasn´t able to find a way to to this.
This are the two ways i found. But cause none of them is suitable for my purpose as they are my question is:
Is there a way to import everything except the empty lines at the end, but including text-style informations, tables and everything else from a PDF to my document using iText?
You can trim away empty space of the XSLT generated PDF and then import the trimmed pages as in your code.
Example code
The following code borrows from the code in my answer to Using iTextPDF to trim a page's whitespace. In contrast to the code there, though, we have to manipulate the media box, not the crop box, because this is the only box respected by PdfWriter.getImportedPage.
Before importing a page from a given PdfReader, crop it using this method:
static void cropPdf(PdfReader reader) throws IOException
{
int n = reader.getNumberOfPages();
for (int i = 1; i <= n; i++)
{
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
MarginFinder finder = parser.processContent(i, new MarginFinder());
Rectangle rect = new Rectangle(finder.getLlx(), finder.getLly(), finder.getUrx(), finder.getUry());
PdfDictionary page = reader.getPageN(i);
page.put(PdfName.MEDIABOX, new PdfArray(new float[]{rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop()}));
}
}
(excerpt from ImportPageWithoutFreeSpace.java)
The extended render listener MarginFinder is taken as is from the question linked to above. You can find a copy here: MarginFinder.java.
Example run
Using this code
PdfReader readerText = new PdfReader(docText);
cropPdf(readerText);
PdfReader readerGraphics = new PdfReader(docGraphics);
cropPdf(readerGraphics);
try ( FileOutputStream fos = new FileOutputStream(new File(RESULT_FOLDER, "importPages.pdf")))
{
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, fos);
document.open();
document.add(new Paragraph("Let's import 'textOnly.pdf'", new Font(FontFamily.HELVETICA, 12, Font.BOLD)));
document.add(Image.getInstance(writer.getImportedPage(readerText, 1)));
document.add(new Paragraph("and now 'graphicsOnly.pdf'", new Font(FontFamily.HELVETICA, 12, Font.BOLD)));
document.add(Image.getInstance(writer.getImportedPage(readerGraphics, 1)));
document.add(new Paragraph("That's all, folks!", new Font(FontFamily.HELVETICA, 12, Font.BOLD)));
document.close();
}
finally
{
readerText.close();
readerGraphics.close();
}
(excerpt from unit test method testImportPages in ImportPageWithoutFreeSpace.java)
I imported both the page from the docText document
and the page from the docGraphics document
into a new document with some text before, between, and after. The result:
As you can see, source styles are preserved but free space around is discarded.
I have a array of Strings as follows :-
String[] data = {“Sunday”,”Monday”,”Tuesday”,”Wednesday”,”Thursday”,”Friday”,”Saturday”}.
Now I want to write this data strings to a pdf file one below the other like :-
1. Sunday
2. Monday
3. Tuesday
4. Wednesday
5. Thursday
6. Friday
7. Saturday.
I am using itext to achieve this. Below is the code snippet I am using
for(int i= 0; i< data.length;i++)
{
Document document=new Document();
PdfWriter.getInstance(document, new FileOutputStream(directory));
document.open();
document.add(new Paragraph(data[i]));
document.add(Chunk.NEWLINE);
document.close();
}
Problem :-
The pdf file which I get has only :-
Saturday.
Please help.
The problem is, you are creating the document in the loop. Try this:
Document document=new Document();
PdfWriter.getInstance(document, new FileOutputStream(directory));
document.open();
for(int i= 0; i< data.length;i++)
{
document.add(new Paragraph(data[i]));
document.add(Chunk.NEWLINE);
}
document.close();
You might want to handle closing of the stream in case something happens.
With Java 7 or above you can achieve with this:
Document document=new Document();
try (FileOutputStream fos = new FileOutputStream(directory)) {
PdfWriter.getInstance(document, fos);
document.open();
for(int i= 0; i< data.length;i++)
{
document.add(new Paragraph(data[i]));
document.add(Chunk.NEWLINE);
}
//EDIT start
document.close();
//EDIT end
}
You are creating document in a loop and also closing same.
make sure document is open and close only once in its lifetime.
try
{
Document document=new Document();
PdfWriter.getInstance(document, new FileOutputStream(directory));
document.open();
for(int i= 0; i< data.length;i++)
{
document.add(new Paragraph(data[i]));
document.add(Chunk.NEWLINE);
}
}
finally{
document.close();
}
I have a function in java which contains the code to generate the pdf file and save into the system local disk.Now as per my requirement i have to make a jsp page which contains a form from where user can dynamically set the date and time on which he needs pdf to be generated.Now pdf should be generated as per the user input given and user input is dynamic in nature it can be changed..
For example ..
Suppose user has set pdf to be created on 15 of every month at 10:00 am..Then this time it should generate the pdf on 15 at 10:00a am..
Now if his requirement change he can set it to 10 of every month at 10:00 am ..and so on..
I am not able to get the way to proceed..
Here is my pdf generation code in POJO file..
OutputStream file = new FileOutputStream(new File("D://timer.pdf"));
Document document = new Document();
PdfWriter.getInstance(document, file);
//Inserting Table in PDF
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Paragraph("Java4s.com"));
cell.setColspan(3);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setPadding(10.0f);
cell.setBackgroundColor(new BaseColor(140, 221, 8));
table.addCell(cell);
table.addCell("Name");
table.addCell("Address");
table.addCell("Country");
table.addCell("Java4s");
table.addCell("NC");
table.addCell("United States");
table.setSpacingBefore(30.0f); // Space Before table starts, like margin-top in CSS
table.setSpacingAfter(30.0f); // Space After table starts, like margin-Bottom in CSS
//Inserting List in PDF
List list = new List(true, 30);
list.add(new ListItem("Java4s"));
list.add(new ListItem("Php4s"));
list.add(new ListItem("Some Thing..."));
//Text formating in PDF
Chunk chunk = new Chunk("Welecome To Java4s Programming Blog...");
chunk.setUnderline(+1f, -2f);//1st co-ordinate is for line width,2nd is space between
Chunk chunk1 = new Chunk("Php4s.com");
chunk1.setUnderline(+4f, -8f);
chunk1.setBackground(new BaseColor(17, 46, 193));
//Now Insert Every Thing Into PDF Document
document.open();//PDF document opened........
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.add(new Paragraph("Dear Java4s.com"));
document.add(new Paragraph("Document Generated On - " + new Date().toString()));
document.add(table);
document.add(chunk);
document.add(chunk1);
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.newPage(); //Opened new page
document.add(list); //In the new page we are going to add list
document.close();
file.close();
System.out.println("Pdf created successfully..");
Thanks in advance..
Use the java.util.Timer class. There is a lot of example on this site.
As someone mentioned in the comments that going with ScheduledExecutorService would be better. (The javadoc already has a tutorial on that subject.)
You can use Timer and Task classes which are of java
I am working with Java and I was wondering how to do a page break in a PDF file? After 50 lines I want to start writing on a new page.
I am using the iText library.
You can use the iText library for creating a PDF in Java
Document document = new Document();
try {
PdfWriter.getInstance(document,
new FileOutputStream("HelloWorld.pdf"));
document.open();
document.add(
new Paragraph("Hello World"));
document.newpage();
// You are on the new page from here.
// Note that newpage method won't work on empty pages,
// so first you should add something to previous page and then call this method
// to create new page
} catch (Exception e) {
// handle exception
}
document.close();