PDF Generation using iText XFA from template - itext

I am trying to generate pdf from template using iText XfaForm. I have to put dynamic table and i am partially successful in displaying dynamic table with data but the if the table has lot of data, it is not adding new page in PDF. only it is displaying the data that can fit into a single page. I created template using Adobe Experience Manager. Please let me know how to fix this issue.
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
AcroFields form = stamper.getAcroFields();
XfaForm xfa = form.getXfa();
xfa.fillXfaForm(new FileInputStream(dataFile));
stamper.close();
reader.close();

Related

Is there a way to insert XFA form values on a reader enabled LiveCycle PDF with itext 7 using append mode?

I need to input XFA form field values into a LiveCycle reader-enabled PDF using iText 7. I can do this successfully but if I don't open the PDF in append mode then it appears the Adobe signature gets broken and the form values cannot be further edited by a user and saved again. If I open the PDF with iText 7 in append mode and change the XFA form field values, the signature from being reader-enabled does not get broken but the changed values aren't showing up on the form. It seems like a bug with iText 7 and changing XFA form field values with append mode possibly. Has anyone successfully done this?
There was a bug in filling XFA Forms in append mode in iText7. This has been fixed in 7.0.2 (and 7.0.2-SNAPSHOT).
The fill a form in append mode, you need the following piece of code:
PdfDocument pdfdoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST),
new StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfdoc, true);
XfaForm xfa = form.getXfaForm();
xfa.fillXfaForm(new FileInputStream(XML));
xfa.write(pdfdoc);
pdfdoc.close();

itext7 pdf to image

I am using iText7(java) and am looking for a way to convert a pdf page to image.
In older iText versions you could do this :
PdfImportedPage page = writer.getImportedPage(reader, 1);
Image image = Image.getInstance(page);
But iText7 does not have PdfImportedPage .
My use case, I have a one page pdf file. I need to add a table and resize the pdf contents to fit a single page. In old iText I would create a page , add table, convert existing pdf page to image, resize image and add that resized image to new page. Is there a new way to do this in iText7.
Thanks to Bruno's answer I got this working with following code :
PdfPage origPage = readerDoc.getPage(1);
Rectangle rect = origPage.getPageSize();
Document document = new Document(writerDoc);
Table wrapperTable = new Table(1);
Table containerTable = new Table(new float[]{0.5f,0.5f});
containerTable.setWidthPercent(100);
containerTable.addCell( "col1");
containerTable.addCell("col2");
PdfFormXObject pageCopy = origPage.copyAsFormXObject(writerDoc);
Image image = new Image(pageCopy);
image.setBorder(Border.NO_BORDER);
image.setAutoScale(true);
image.setHeight(rect.getHeight()-250);
wrapperTable.addCell(new Cell().add(containerTable).setBorder(Border.NO_BORDER));
wrapperTable.addCell(new Cell().add(image).setBorder(Border.NO_BORDER));
document.add(wrapperTable);
document.close();
readerDoc.close();
Please read the official documentation for iText 7, more specifically Chapter 6: Reusing existing PDF documents
In PDF, there's the concept of Form XObjects. A Form XObject is a piece of PDF content that is stored outside the content stream of a page, hence XObject which stands for eXternal Object. The use of the word Form in Form XObject could be confusing, because people might be thinking of a form as in a fillable form with fields. To avoid that confusing, we introduced the term PdfTemplate in iText 5.
The class PdfImportedPage you refer to was a subclass of PdfTemplate: it was a piece of PDF syntax that could be reused in another page. Over the years, we noticed that people also got confused by the word PdfTemplate.
In iText 7, we returned to the basics. When talking about a Form XObject, we use the class PdfFormXObject. When talking about a page in a PDF file, we use the class PdfPage.
This is how we get a PdfPage from an existing document:
PdfDocument origPdf = new PdfDocument(new PdfReader(src));
PdfPage origPage = origPdf.getPage(1);
This is how we use that page in a new document:
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
PdfFormXObject pageCopy = origPage.copyAsFormXObject(pdf);
If you want to use that pageCopy as an Image, just create it like this:
Image image = new Image(pageCopy);

Setting AcroField text color in itextSharp

I am using iTextSharp 5.5.3 i have a PDF with named fields i created with Adobe lifecycle I am able to fill the fields using iTextSharp but when i change the textcolor for a field it does not change. i really dont know why this is so. here is my code below
form.SetField("name", "Michael Okpara");
form.SetField("session", "2014/2015");
form.SetField("term", "1st Term");
form.SetFieldProperty("name", "textcolor", BaseColor.RED, null);
form.RegenerateField("name");
If your form is created using Adobe LifeCycle, then there are two options:
You have a pure XFA form. XFA stands for the XML Forms Architecture and your PDF is nothing more than a container of an XML stream. There is hardly any PDF syntax in the document and there are no AcroForm fields. I don't think this is the case, because you are still able to fill out the fields (which wouldn't work if you had a pure XFA form).
You have a hybrid form. In this case, the form is described twice inside the PDF file: once using an XML stream (XFA) and once using PDF syntax (AcroForm). iText will fill out the fields in both descriptions, but the XFA description gets preference when rendering the document. Changing the color of a field (or other properties) would require changing the XML and iText(Sharp) can not do that.
If I may make an educated guess, I would say that you have a hybrid form and that you are only changing the text color of the AcroForm field without changing the text color in the XFA field (which is really hard to achieve).
Please try adding this line:
form.RemoveXfa();
This will remove the XFA stream, resulting in a form that only keeps the AcroForm description.
I have written a small example named RemoveXFA using the form you shared to demonstrate this. This is the C#/iTextSharp version of that example:
public void ManipulatePdf(String src, String dest)
{
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
AcroFields form = stamper.AcroFields;
form.RemoveXfa();
IDictionary<String, AcroFields.Item> fields = form.Fields;
foreach (String name in fields.Keys)
{
if (name.IndexOf("Total") > 0)
form.SetFieldProperty(name, "textcolor", BaseColor.RED, null);
form.SetField(name, "X");
}
stamper.Close();
reader.Close();
}
In this example, I remove the XFA stream and I look over all the remaining AcroFields. I change the textcolor of all the fields with the word "Total" in their name, and I fill out every field with an "X".
The result looks like this: reportcard.pdf
All the fields show the letter "X", but the fields in the TOTAL column are written in red.
I finally found a way, guess the problem was coming from using Adobe LC, so i switched to Open Office it all worked but when i flatten the form everything disappears. I found a solution to that here ITextSharp PDFTemplate FormFlattening removes filled data
Thanks Mr Lowagie for your help

Creating a PDF image in iText

I'm trying to add an image that I have on the filesystem as a pdf into a pdf that I'm creating on the fly.
I tried to use the Image class, but it seems that it does not work with PDFs (only JPEG, PNG or GIF). How can I create an element from an existing PDF, so that I can place it in my new PDF?
Please download chapter 6 of my book and read all about the class PdfImportedPage.
In the most basic example, you'd create a PdfReader instance and import the page into the PdfWriter instance, from which point on you can use the PdfImportedPage instance, either directly, or wrapped inside an Image object:
PdfReader reader = new PdfReader(existingPdf);
PdfImportedPage page = writer.getImportedPage(reader, i);
Image img = Image.getInstance(page);
reader.close();

Inserting a "linked rectangle" with itext

I want to insert a hyperlink into an existing PDF at a position I know in advance: I already have the coordinates of a rectangle on a given page. I want to link this rectangle to another page of the same PDF (which I also know in advance).
How do I achieve this?
Please take a look at the AddLinkAnnotation example.
As you (should) already know (but you didn't show what you've already tried, which is kind of mandatory on StackOverflow), you can use PdfStamper to manipulate an existing PDF. Adding a rectangular link on one page to another page, is as simple as adding a link annotation to that page:
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
Rectangle linkLocation = new Rectangle(523, 770, 559, 806);
PdfDestination destination = new PdfDestination(PdfDestination.FIT);
PdfAnnotation link = PdfAnnotation.createLink(stamper.getWriter(),
linkLocation, PdfAnnotation.HIGHLIGHT_INVERT,
3, destination);
link.setBorder(new PdfBorderArray(0, 0, 0));
stamper.addAnnotation(link, 1);
stamper.close();
The link object is created using:
the writer instance tied to the stamper,
the rectangle (the position you say you know in advance,
a highlighting option (pick one: HIGHLIGHT_NONE, HIGHLIGHT_INVERT, HIGHLIGHT_OUTLINE, HIGHLIGHT_PUSH, HIGHLIGHT_TOGGLE),
the page you want to link to,
a destination (different options are possible, see The ABC of PDF).
Once you have an instance of PdfAnnotation, you can add it to a specific page using the addAnnotation() method.