Reputation: 1486
I'm trying to create a PDF using iText and I'm having a great deal of difficulty. In short, what I want to do is:
So far, it's looking like this
// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);
// create a table in a new document
Document document = new Document();
PdfCopy copy = new PdfCopy(document, os);
document.open();
PdfPTable table = new PdfPTable(2);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
document.add(table);
Can someone explain how I can make a copy of the template once I've used PdfReader to read it? Is there a way to write the table onto the template copy and not a new document?
For future references, here's what I've done:
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline;filename=\"scheduler-labels.pdf\"");
ServletOutputStream os = response.getOutputStream();
// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);
// make new pdf document to draw table and output to memory
Document document = new Document(reader.getPageSize(1));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// write table
document.open();
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(110);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 2"));
table.addCell(cell);
document.add(table);
document.close();
// read in newly generated table pdf
PdfReader tableReader = new PdfReader(baos.toByteArray());
ByteArrayOutputStream baosCombined = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(tableReader, baosCombined);
// get a page from the template pdf
PdfImportedPage page = stamper.getImportedPage(reader, 1);
// add to background of table pdf
PdfContentByte background;
background = stamper.getUnderContent(1);
background.addTemplate(page, 0, 0);
stamper.close();
tableReader.close();
reader.close();
// write to servlet output
baosCombined.writeTo(os);
os.flush();
os.close();
Upvotes: 0
Views: 6368
Reputation: 95928
As studying the sample referenced in my comment was just what [Tuan] needed, I formulate it as an answer:
The sample Stationery.java from chapter 6 of iText in Action — 2nd Edition essentially shows how to use the contents of a given PDF as background (stationery-like) of a new PDF while filling its foreground with new content.
The central code is as follows:
public class Stationery extends PdfPageEventHelper
{
[...]
public void createPdf(String filename) throws Exception
{
// step 1
Document document = new Document(PageSize.A4, 36, 36, 72, 36);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
useStationary(writer);
// step 3
document.open();
// step 4
[... add content to PDF ...]
// step 5
document.close();
}
[...]
public void useStationary(PdfWriter writer) throws IOException
{
writer.setPageEvent(this);
PdfReader reader = new PdfReader(STATIONERY);
page = writer.getImportedPage(reader, 1);
}
public void onEndPage(PdfWriter writer, Document document)
{
writer.getDirectContentUnder().addTemplate(page, 0, 0);
}
[...]
}
As implicit close()
calls have been removed more and more recently, the PdfReader reader
instantiated in useStationary
nowerdays should be stored in some variable of Stationery
and closed after createPdf
has executed.
Upvotes: 0