Add new AcroForm field to a PDF - pdf

I have used iText to fill data into existing AcroForm fields in a PDF.
I am now looking for a solution to add new AcroForm fields to a PDF. Is this possible with iText? If so, how can I do this?

This is documented in the official documentation, more specifically in the SubmitForm example. When using a tool such as iText, you should read the official documentation first ;-)
Anyway, I've written you a simple example called AddField. It adds a button field at a specific position defined by new Rectangle(36, 700, 72, 730).
public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
PushbuttonField button = new PushbuttonField(
stamper.getWriter(), new Rectangle(36, 700, 72, 730), "post");
button.setText("POST");
button.setBackgroundColor(new GrayColor(0.7f));
button.setVisibility(PushbuttonField.VISIBLE_BUT_DOES_NOT_PRINT);
PdfFormField submit = button.getField();
submit.setAction(PdfAction.createSubmitForm(
"http://itextpdf.com:8180/book/request", null,
PdfAction.SUBMIT_HTML_FORMAT | PdfAction.SUBMIT_COORDINATES));
stamper.addAnnotation(submit, 1);
stamper.close();
}
}
As you can see, you need to create a PdfFormField object (using helper classes such as PushbuttonField, TextField,...) and then use PdfStamper's addAnnotation() method to add the field to a specific page.

Related

How to create PDF/UA in iText7 with text hyperlink

I am trying to create a PDF/UA compliant file that contains a text hyperlink with iText 7. Both the Acrobat Preflight test for PDF/UA and the PDF Accessibility Checker (PAC 3) complain that the PDF file say that the PDF is not compliant.
PAC 3 says ""Link" annotation is not nested inside a "Link" structure element" and the Acrobat Preflight test says the Link annotation does not have an alternate description in the Contents key.
The following is my attempt to create PDF/UA compliant output that contains a text hyperlink.
Any advice would be appreciated.
public void testHyperLink() throws IOException {
// Create PDF/UA with text hyperlink
String filename = "./results/HyperLink.pdf";
WriterProperties properties = new WriterProperties();
properties.addUAXmpMetadata().setPdfVersion(PdfVersion.PDF_1_7);
PdfWriter writer = new PdfWriter(filename, properties);
pdfDoc = new PdfDocument(writer);
//Make document tagged
pdfDoc.setTagged();
pdfDoc.getCatalog().setLang(new PdfString("en-US"));
pdfDoc.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));
PdfDocumentInfo info = pdfDoc.getDocumentInfo();
info.setTitle("Hello Hyperlinks!");
document = new Document(pdfDoc);
// Must embed font for PDF/UA
byte[] inputBytes = Files.readAllBytes(Paths.get("./resources/fonts/opensans-regular.ttf"));
boolean embedded = true;
boolean cached = false;
PdfFont font = PdfFontFactory.createFont(inputBytes, PdfEncodings.CP1252, embedded, cached);
Text text = new Text("This is a Text link");
text.setFont(font);
text.setFontSize(16F);
// Add alternate text for hyperlink
text.getAccessibilityProperties().setAlternateDescription("Click here to go to the iText website");
PdfAction act = PdfAction.createURI("https://itextpdf.com/");
text.setAction(act);
Paragraph para = new Paragraph();
para.add(text);
document.add(para);
document.close();
System.out.println("Created "+ filename);
}
A Link object might be what you want:
Link lnk = new Link("This is a Text link",
PdfAction.CreateURI("https://itextpdf.com/"));
lnk.SetFont(font);
lnk.GetLinkAnnotation().SetBorder(new PdfAnnotationBorder(0, 0, 0));//Remove the default border
lnk.GetAccessibilityProperties().SetAlternateDescription("Click here to go to the iText website");
Paragraph para = new Paragraph();
para.Add(lnk);
document.Add(para);

How to add an image to a pdf file in APPEND mode using PdfStamper?

I'm using the iTextSharp library version 5.5.6.0.
This file contains customizable text fields and it's necessary to keep an interactive text form fields: https://yadi.sk/i/yoUvDI9EmtVhc .
But I can't adding an image in PdfTemplate object.
The code in c# at this stage is:
string outpath = #"D:\pdf_\output.pdf";
string inpath = #"D:\pdf_\input.pdf";
string stamp = #"D:\pdf_\img.png";
This method does'nt add the image, but the text boxes are active.
public static void onlyInteractive()
{
using (MemoryStream os = new MemoryStream())
using (PdfReader pdfReader = new PdfReader(inpath))
//APPEND mode
using (PdfStamper stamper = new PdfStamper(pdfReader, os, '\0', true))
{
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(stamp);
image.SetAbsolutePosition(0, 0);
PdfTemplate template = PdfTemplate.CreateTemplate(stamper.Writer, image.Width, image.Height);
template.AddImage(image);
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
os.WriteTo(new FileStream(outpath, FileMode.Create, FileAccess.ReadWrite));
}
}
The behavior of this method back to the first.
public static void onlyImage()
{
using (Stream output = new FileStream(outpath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
using (PdfReader reader = new PdfReader(inpath))
using (var stamper = new PdfStamper(reader, output, '\0', true))
{
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(stamp);
image.SetAbsolutePosition(0, 0);
PdfTemplate template = PdfTemplate.CreateTemplate(stamper.Writer, image.Width, image.Height);
template.AddImage(image);
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
}
}
onlyInteractive
The issue with this code is that you grab the output PDF before it is finished:
using (PdfStamper stamper = new PdfStamper(pdfReader, os, '\0', true))
{
[...]
os.WriteTo(new FileStream(outpath, FileMode.Create, FileAccess.ReadWrite));
}
When the stamper is getting closed (here implicitly at the end of its using block), some not yet stored PDF objects are written and the internal cross references and the file trailer are written.
You write the os contents to file before that. Thus, your result document is incomplete. Adobe Reader upon opening it repairs it which results in essentially your original document.
onlyImage
This code by itself is correct, it stamps the image onto the document and stores it correctly.
Your problem here is that the document itself is Reader-enabled, i.e. it is signed with a so called usage rights signature. Such signatures tell Adobe Reader upon opening a file to make additional features available displaying editing the document in question.
But when checking the signature on the document with the image, Adobe Reader sees that the document has been changed in a way that is not compatible with the usage rights granted by the signature: An image has been added to the page content which is something not granted by the signature. Thus, Adobe Reader revokes the granted features, in your case form editing.
Removing the usage rights signature
One option in this situation is to remove that signature. In that case form editing is not granted anymore by means of that signature. But in newer Adobe Reader versions (since version XI if I recall correctly) form editing has been granted to all documents by default! In your case that feature is removed due to the invalidated signature!
This can be done as follows:
using (Stream output = new FileStream(outpath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
using (PdfReader reader = new PdfReader(inpath))
using (var stamper = new PdfStamper(reader, output))
{
reader.RemoveUsageRights();
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(stamp);
image.SetAbsolutePosition(0, 0);
PdfTemplate template = PdfTemplate.CreateTemplate(stamper.Writer, image.Width, image.Height);
template.AddImage(image);
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
}
You can now edit the PDF with image in newer Adobe Readers.
Unfortunately, though, there is an error upon saving the document. I don't know whether they have to do with the fact that the source document is partially invalid (Adobe Preflight complains about a number of issues, foremost the use of an undefined encoding name Win1251Encoding) or whether something else gets broken.
Removing the usage rights signature in append mode
Working in append mode we have to manually remove the usage rights signature. Actually, we'll remove the whole Perms dictionary from the Catalog:
using (Stream output = new FileStream(outpath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
using (PdfReader reader = new PdfReader(inpath))
using (var stamper = new PdfStamper(reader, output, '\0', true))
{
reader.Catalog.Remove(PdfName.PERMS);
stamper.MarkUsed(reader.Catalog);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(stamp);
image.SetAbsolutePosition(0, 0);
PdfTemplate template = PdfTemplate.CreateTemplate(stamper.Writer, image.Width, image.Height);
template.AddImage(image);
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
}
Now you can edit the form and save the file (at least I can in Adobe Reader DC).
PS: The correct coordinates
In a comment the OP shared another PDF and stated that it
for the other file is impossible to place a picture on a page with landscape orientation.
There indeed is an issue in the OP's code:
stamper.GetOverContent(1).AddTemplate(template, 150, 200, true);
The fixed coordinates 150, 200 are a sign that the OP assumes the lower left page corner to be the origin 0, 0 of the coordinate system. While this often is the case, this is not necessarily true. One always has to take the CropBox (which defaults to the MediaBox) into account, i.e. for the OP's code:
Rectangle cropBox = reader.GetCropBox(1);
stamper.GetOverContent(1).AddTemplate(template, cropBox.Left + 150, cropBox.Bottom + 200, true);
the library takes rotation not correctly, but gives 0 degrees.
But that is correct! Your sample PDF is somewhat special as it uses an unrotated rectangle for landscape and a rotated rectangle for portrait.

How to insert data into existing pdf template text filed with bold and also it is editable using itext?

This is my code
String soruce="E:\\PT\\iText\\TextBox.pdf";
String destination="E:\\PT\\iText\\TextBoxOP.pdf";
PdfReader reader = new PdfReader(soruce);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destination));
AcroFields form = stamper.getAcroFields();
form.setField("Text1", "Bruno Lowagie");
I need Bruno Lowagie Like this in pdf text field
Try This
Below is the action file with the help of which I was able to get What I needed..
https://pranavom.wordpress.com/2011/03/15/modify-pdf-using-fpdffpdi-library/

itextsharp stamper vs smartcopy, show pdf in browser without toolbar or navpanes

My application is grabbing pdf bytes from our db and sending the pdf to an iframe, using the itextsharp library. When the pdf is displayed in the iframe, the toolbar and navigation pane show, but we'd like to hide those. When I load a pdf document by simply typing in the pdf's url with #toolbar=0&navpanes=0, I see the result I'm looking for.
The application logic is using PdfStamper to add some buttons and other data to the pdf. When I write the pdf to the Response.Outputstream, the pdf shows up with the added buttons, and all is good except that I can't get rid of the toolbar and navpanes. I've tried adding "toolbar=0&navpanes=0" to the url in the response header, but to no avail.
I've written a test application which shows that using PdfSmartCopy instead of the stamper works perfectly - the pdf is shown in the browser which hides the toolbar and navpane by default.
The problem is that I still need to add some buttons to the pdf via the stamper. I've written a test app which adds the buttons via the stamper, then the smart copy grabs each page from the stamper and writes all this out to the Response.Output. The pdf shows in the browser with no toolbar or navpanes, but the buttons are not there.
Here is the code which uses both the stamper and the smart copy - your help is greatly appreciated:
private void SendStamperToCopy()
{
try
{
String filePath = #"C:\debug\PerfIndicWithDefaults.pdf";
byte[] pdfBytes = ReadFile(filePath);
Document document = new Document();
PdfSmartCopy copy = new PdfSmartCopy(document, Response.OutputStream);
document.Open();
MemoryStream memStream = new MemoryStream();
PdfReader reader = new PdfReader(pdfBytes);
PdfStamper pdfStamper = new PdfStamper(reader, memStream);
// add a button with the stamper
iTextSharp.text.Rectangle rectCancel = new iTextSharp.text.Rectangle(50, 50, 20, 20);
PushbuttonField btnCancel = new PushbuttonField(pdfStamper.Writer, rectCancel, "Cancel");
btnCancel.Text = "Cancel";
iTextSharp.text.pdf.PdfAnnotation fieldCancel = btnCancel.Field;
pdfStamper.AddAnnotation(fieldCancel, 1);
int numOfPgs = reader.NumberOfPages;
for (int n = 1; n <= numOfPgs; n++)
{
copy.AddPage(pdfStamper.GetImportedPage(reader, n));
}
String headerStr = "inline; filename=PerfIndicWithDefaults.pdf";
Response.AppendHeader("content-disposition", headerStr);
Response.ContentType = "application/pdf";
Response.OutputStream.Flush();
document.Close();
Response.OutputStream.Close();
}
catch (Exception ex)
{
Console.Write(ex);
Response.OutputStream.Flush();
Response.OutputStream.Close();
}
}
If I understand your question correctly, you want to use PdfStamper to add a button and you want to change the viewer preferences. This can be done like this:
PdfReader reader = new PdfReader(source);
System.IO.MemoryStream m = new System.IO.MemoryStream();
PdfStamper stamper = new PdfStamper(reader, m);
PdfStamper.ViewerPreferences = PdfWriter.HideToolbar | PdfWriter.PageModeUseNone;
stamper.Close();
reader.Close();
The HideToolbar will hide the toolbar, whereas PageModeUseNone means that you don't show any panels (such as the bookmarks panel, etc...).
It is not clear why you would need PdfSmartCopy in this context. Maybe I'm missing something. Also: there are some strange errors in your code: you never close the stamper instance, yet you import a page from the stamper into the copy instance. I've never seen any one try that. It's certainly not what I had in mind when I wrote iText. Your code is very confusing to me.

Dynamically Fill your PDF Forms using silverlight

string pdfTemplate = #"Trust App form.pdf";
string newFile = #"Trust App form Completed.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(
newFile, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("trust.trustee.entityname.line1", "Gulistan-e-Jauhar Karachi");
pdfStamper.FormFlattening = false;
pdfStamper.Close();
I am able to fill pdf forms using Itext sharp pdf.
But problem is this pdf is for .net. I WANT TO USE IT IN SILVERLIGHT.
Is there any alternative? for filling pdf form in silverlight... what i think itext sharp give silverpdf (http://silverpdf.codeplex.com/) but there is pdfstamper and acrofields classes in silverpdf.
SilverPDF looks to be inspired/based-on iTextSharp and PDFSharp, but it doesn't use an identical class layout by any means.
I just poked around in their code a bit (they have no docs that I could find), and it looks like you need to get the field's PdfAcroField object from the PdfAcroForm, which you get from a PdfDocument, which in turn you get from PdfReader.open(...).
When the docs aren't good enough, check the code if at all possible.