Using itextsharp v5.5.5.0 in VS2010
Setting the stamper FormFlattening = true no filed data is written to the output pdf. If set false the data is all present & correct but still editable (which I don't want)
PdfReader pdfTemplate = new PdfReader("..\\..\\pdf\\BFC-Template.pdf");
FileStream fileOutputStream = new FileStream("..\\..\\pdf\\BFC.pdf", FileMode.Create);
PdfStamper stamper = new PdfStamper(pdfTemplate, fileOutputStream);
stamper.AcroFields.SetField("FitID", "1234");
stamper.AcroFields.SetField("FitBy", "Fred Flintstone");
stamper.AcroFields.SetField("FitDate", "03/11/2015");
stamper.AcroFields.SetField("FitLocation", "Bedrock");
stamper.FormFlattening = true;
stamper.Close();
pdfTemplate.Close();
fileOutputStream.Close();
Try adding :
stamper.AcroFields.GenerateAppearances = true;
EDIT:
If your form is a Dynamic Form. you might need to change
stamper.AcroFields.SetField("FitID", "1234");
to:
stamper.AcroFields.Xfa.DatasetsSom.Name2Node["FitID"].InnerText = "1234"
It shouldn't matter, but you could try instantiating a AcroFields object from the pdfStamper field.
PdfStamper stamper = new PdfStamper(pdfTemplate, fileOutputStream);
AcroFields pdfFields = pdfStamper.AcroFields;
Then you can just set each field using pdfFields:
pdfFields.SetField("FitID", "1234");
pdfFields.SetField("FitBy", "Fred Flintstone");
pdfFields.SetField("FitDate", "03/11/2015");
pdfFields.SetField("FitLocation", "Bedrock");
stamper.FormFlattening = true;
stamper.Close();
I have this exact setup and it works for me.
Related
So I am trying to adjust this function so instead of creating a new PDF file with the new fields value, then display new file to user then delete on exit.
to just create maybe a stream or byte array of this template with the new fields value and just display it for user.. is it possible?
private void fillPDFForm()
{
string formFile = #"C:\fw4.pdf";
string newFile = #"C:\New_fw4.pdf";
PdfReader reader = new PdfReader(formFile);
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create)))
{
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("name", "John Doe");
fields.SetField("address", "xxxxx, yyyy");
fields.SetField("postal_code", "12345");
fields.SetField("email", "johndoe#xxx.com");
// flatten form fields and close document
stamper.FormFlattening = true;
stamper.Close();
}
}
Yes Of-course it is possible by using MemoryStream instead of FileStream thus your code would look like:
using (MemoryStream memStream = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, memStream, '\0', true))
{
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("name", "John Doe");
fields.SetField("address", "xxxxx, yyyy");
fields.SetField("postal_code", "12345");
fields.SetField("email", "johndoe#xxx.com");
// flatten form fields and close document
stamper.FormFlattening = true;
stamper.Close();
}
return memStream.ToArray();
}
Did you try to set the content type for the response to application/pdf ?
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create)))
to
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create), "application/pdf"))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create)))
private void fillPDFForm()
{
string formFile = #"C:\fw4.pdf";
string newFile = #"C:\New_fw4.pdf";
PdfReader reader = new PdfReader(formFile);
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create), "application/pdf"))
{
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("name", "John Doe");
fields.SetField("address", "xxxxx, yyyy");
fields.SetField("postal_code", "12345");
fields.SetField("email", "johndoe#xxx.com");
// flatten form fields and close document
stamper.FormFlattening = true;
stamper.Close();
}
}
I have simply pdf form (generated from Adobe Acrobat - test_pdf) with two editable textboxes and one radio button group with 3 options.
How I can choose the correct option and mark this on pdf template?
When I set radiobutton fields as below:
string pdfTemplate = #"c:\Temp\PDF\fw4.pdf";
string newFile = #"c:\Temp\PDF\completed_fw4.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("Text1", "test1");
pdfFormFields.SetField("Text2", "test2");
var radiobuttons = pdfFormFields.GetAppearanceStates("Group3");
foreach (string rb in radiobuttons)
{
if (rb != "Off")
{
if (rb == "Wybór1")
{
pdfFormFields.SetField(rb, "On");
}
else
{
pdfFormFields.SetField(rb, "Off");
}
}
}
pdfStamper.FormFlattening = true;
pdfStamper.Close();
unfortunately always last button is set as 'On' (I would like to set first button in this example).
How I should construct 'foreach' loop?
Thank you in advance for any suggestions.
I found the solution:
string pdfTemplate = #"c:\Temp\PDF\fw4.pdf";
string newFile = #"c:\Temp\PDF\completed_fw4.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("Text1", "test1");
pdfFormFields.SetField("Text2", "test2");
pdfFormFields.SetField("Group3", "Wybór1"); // it's only 1 line
pdfStamper.FormFlattening = true;
pdfStamper.Close();
Here is my chunk of code. It compiles fine and when I fire off the event I get the email, but I then get this error
Email attachment ERROR on Adobe while opening(Acrobat could not open 'Att00002.pdf' because it is either not a supported file type or because the file has been damaged(for example, it was sent as an email attachment and wasnt correctly decoded.)
string agentName = "My Name";
MemoryStream _output = new MemoryStream();
PdfReader reader = new PdfReader("/pdf/Agent/Specialist_Certificate.pdf");
using (PdfStamper stamper = new PdfStamper(reader, _output))
{
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("FIELD_AGENT_NAME", agentName);
fields.SetField("FIELD_DATE", AvalonDate);
// flatten form fields and close document
stamper.FormFlattening = true;
SendEmail(_output);
DownloadAsPDF(_output);
stamper.Close();
}
private void SendEmail(MemoryStream ms)
{
Attachment attach = new Attachment(ms, new System.Net.Mime.ContentType("application/pdf"));
EmailHelper.SendEMail("myemail#myemail.com", "mjones#globusfamily.com", null, "", "Avalon Cert", "Hope this works", EmailHelper.EmailFormat.Html,attach);
}
EDITED *************************************
using (MemoryStream _output = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, _output))
{
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("FIELD_AGENT_NAME", agentName);
fields.SetField("FIELD_DATE", AvalonDate);
// flatten form fields and close document
stamper.FormFlattening = true;
}
SendEmail(_output);
}
You're calling stamper.close() inside the using (PdfStamper stamper = new PdfStamper(reader, _output)). The using will automatically close the stamper upon exiting it in addition to your manual close(), so technically the stamper is trying to be closed twice. Because of this it is also trying to close the MemoryStream more than once. That's where the exception is coming from.
I would use the technique located in the answer here for your MemoryStream and PdfStamper (modified and taken from: Getting PdfStamper to work with MemoryStreams (c#, itextsharp)):
using (MemoryStream _output = new MemoryStream()) {
using (PdfStamper stamper = new PdfStamper(reader, _output)) {
// do stuff
}
}
I'm struggling to insert images on a multi-page PDF.
To create several pages I'm using PdfConcatenate, and it works. I get to add pages of my template perfectly. The problem starts when I try to add images. It just doesn't load them.
Here's the code that works to add images:
string pdfTemplate = #"Tools\template.pdf";
string targetPdfPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), fileName + ".pdf");
FileStream output = new FileStream(targetPdfPath, FileMode.Create);
PdfConcatenate pdfConcatenate = new PdfConcatenate(output);
PdfReader pdfReader = new PdfReader(pdfTemplate);
MemoryStream memoryStream = getMemoryStream(output);
PdfStamper pdfStamper = new PdfStamper(pdfReader, output);
int cardIndex = 1;
foreach (Registry reg in registries)
{
setFields(reg, pdfStamper, cardIndex);
if (cardIndex == 4)
{
pdfConcatenate.AddPages(pdfReader);
pdfReader = new PdfReader(pdfTemplate);
pdfStamper = new PdfStamper(pdfReader, output);
cardIndex = 1;
}
else
{
cardIndex++;
}
}
//if (cardIndex != 1)
// pdfConcatenate.AddPages(pdfReader);
//make the form no longer editable
pdfStamper.FormFlattening = true;
pdfStamper.Close();
pdfReader.Close();
//pdfConcatenate.Close();
If use MemoryStream for PdfStamper and uncomment these lines:
//if (cardIndex != 1)
// pdfConcatenate.AddPages(pdfReader);
//pdfConcatenate.Close();
I get it to add pages, but without images.
Any idea of what is wrong?
SOLUTION: (Thanks to #mkl)
string pdfTemplate = #"Tools\template.pdf";
string targetPdfPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), fileName + ".pdf");
FileStream output = new FileStream(targetPdfPath, FileMode.Create);
PdfConcatenate pdfConcatenate = new PdfConcatenate(output);
PdfReader pdfReader = new PdfReader(pdfTemplate);
MemoryStream memoryStream = new MemoryStream();
PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream);
int cardIndex = 1;
foreach (Registry reg in registries)
{
setFields(reg, pdfStamper, cardIndex);
if (cardIndex == 4)
{
pdfStamper.FormFlattening = true;
pdfStamper.Close();
PdfReader tempReader = new PdfReader(memoryStream.ToArray());
pdfConcatenate.AddPages(tempReader);
memoryStream = new MemoryStream();
pdfReader = new PdfReader(pdfTemplate);
pdfStamper = new PdfStamper(pdfReader, memoryStream);
cardIndex = 1;
}
else
{
cardIndex++;
}
}
if (cardIndex != 1)
{
pdfStamper.FormFlattening = true;
pdfStamper.Close();
PdfReader tempReader = new PdfReader(memoryStream.ToArray());
pdfConcatenate.AddPages(tempReader);
tempReader.Close();
}
pdfStamper.Close();
pdfReader.Close();
pdfConcatenate.Close();
The problem most likely is some misconception on how PdfStamperworks. You seem to think it somehow manipulates the data in the PdfReader it stamps, and also pages exported from that reader beforehand. This is not the case, a PdfStamper generates a new PDF file (in its output stream) based on the data in the reader but the contents of the reader itself are not updated to also reflect all the changes (the PdfReader object may be touched in the process, though, and not be reusable afterwards). So...
As already mentioned in the comment, you have the PdfConcatenate and an unknown number of PdfStamper instances all writing the same `FileStream' output. As each of these objects creates an independant PDF, you are lucky if one of then wins because then you'll get at least a proper PDF as output. Otherwise you either get some exception or garbage consisting of multiple intermingled PDFs. Thus, make only PdfConcatenate target your output file.
If your actual intent is to repeatedly fill the template fields with the content of 4 cards each time and combine the results, you should not add the pages from the PdfReader of the template to the PdfConcatenate --- the pages in that reader are not filled in! --- but instead have the PdfStamper output to a MemoryStream, fill its fields, flatten its form, close it, open its output in a new PdfReader, and add all the pages in that reader to the PdfConcatenate.
I don't dare to put that into code as I'm predominantly using Java and writing down untested C# code most likely would include multiple errors... ;)
PS: Currently you count on all the PdfReader instances you open to be implicitly closed somewhere. While that is true currently, recent check-ins in the iText SVN repository seem to indicate that these implicit close calls are removed from the code. Thus, please also start explicitly closing PdfReader instances you dont't use anymore. Otherwise you will soon have to deal with memory leaks due to readers closing much too late..
I try to fill a PDF form with C#. But somehow it does not work. The problem: the fields object (in the line: fields.SetField("Name", "Peter");) seems to be null.
Here is my code:
public static void FillForm()
{
String pdfTemplate = #"c:\Users\Hagen\Desktop\formular.pdf";
String newFile = #"c:\Users\Hagen\Desktop\formular_fertig.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
AcroFields fields = pdfStamper.AcroFields;
fields.SetField("Name", "Peter");
pdfStamper.Close();
}
I remember having a similar problem when I first tried to fill in form fields. The line you have that initializes the pdfStamper;
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
Try adding ReadWrite permissions to the stamper object like so.
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create, FileAccess.ReadWrite));
That MIGHT be your problem. I don't recall exactly how I fixed this problem myself, but that is what jumps out to me initially. It may very well be trying to write in the field value, but the stamper doesn't have the FileAccess it requires to accomplish this.
Hope this helps