ITextSharp stamper corrupting pdf - c#

I am trying to rotate various pages in a pdf document using ITextSharp. It appears that it is working because when I open in adobe, everything looks good. However when trying to re-open in itextsharp, various exceptions are thrown. I can tell something is up with the document because adobe always asks if I want to save the changes when opening a document manipulated with itextsharp, which indicates that it fixed the corruption.
The crazy thing is that I don't even have to do any manipulation to the document, just create a new stamper and close it. Below is the code, stripped down to the point where it still corrupts the document.
Any ideas?
Here is my code
Dim byteArray = IO.File.ReadAllBytes(filename)
Using reader = New iTextSharp.text.pdf.PdfReader(byteArray)
Using stamper = New iTextSharp.text.pdf.PdfStamper(reader, New IO.FileStream(filename, IO.FileMode.OpenOrCreate))
'I don't even have to do anything for it to corrupt, just use a stamper
stamper.Close()
End Using
reader.Close()
End Using

I figured out the problem. I changed this
IO.FileMode.OpenOrCreate
to
IO.FileMode.Create
And it works fine now. I'm not sure why but if anyone else has this issue, I hope this helps.

Related

iText7 usage rights and Adobe Reader

I'm revisiting some old code in an attempt to get this working again. I'm using the code from the iText KB here -> https://kb.itextpdf.com/home/it7kb/faq/how-to-fill-xfa-form-using-itext-without-breaking-usage-rights.
It seems even using that it somehow still breaks the pdf and not then editable with Adobe Reader. Last time I couldn't post the form but have now managed to strip out any important stuff so at least someone can test...hopefully.
I did create a super basic form in Livecycle and reader enable it in Acrobat DC and using the code below it worked fine, yet for some reason this form always breaks.
Here is the code I'm using.
String source = #"D:\Temp\SVTESTx.pdf";
String dest = #"D:\Temp\SVAx.PDF";
PdfReader preader = new PdfReader(source);
PdfDocument pdfDoc=new PdfDocument(preader, new PdfWriter(dest), new StampingProperties().UseAppendMode());
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
XfaForm xfa = form.GetXfaForm();
xfa.FillXfaForm(new FileStream(#"D:\Temp\SVTEST.xml", FileMode.Open, FileAccess.Read));
xfa.Write(pdfDoc);
pdfDoc.Close();
The files in question are here (for the non-working PDF) -> https://drive.google.com/drive/folders/1MET19PUubd-J9D4fbzkX1KJAUbn0aMCZ?usp=sharing
Cheers

PDFSharp saved Document always promps the "Save changes" message after filling form fields

Recently I made a program where I take a pdf file and using PDFsharp fill in the form fields with required values. The code that I made works fine it writes the values just fine but the problem comes after you open the pdf and try to close it, you will get a the standard message "Do you want to save changes before closing" even thou you just opened and close the document. The code that I use looks like this:
string templateDocPath = #"Original.pdf";
using (PdfDocument myTemplate = PdfReader.Open(templateDocPath, PdfDocumentOpenMode.Modify))
{
PdfAcroForm form = myTemplate.AcroForm;
if (form.Elements.ContainsKey("/NeedAppearances"))
{
form.Elements["/NeedAppearances"] = new PdfBoolean(true);
}
else
{
form.Elements.Add("/NeedAppearances", new PdfBoolean(true));
}
PdfTextField testField = (PdfTextField)(form.Fields["Name"]);
testField.Value = new PdfString("NameTest");
testField.ReadOnly = true;
myTemplate.Save(#"Output.pdf");
myTemplate.Close();
}
When I was trying to solved the problem I found out that the message comes only after you add "/NeedAppearances" Element to the AcroForms. You need this element or the values you write on the document will not show.
Googling some more I found a forum (https://forum.pdfsharp.net/viewtopic.php?f=2&t=3741) where someone asked the same question but didn't get a clear answer, the last comment mentioned that "/NeedAppearances" says to the document to generate the new values. So when you open the document new values are generated, so you have to save them.
I would like to know if it's true and is there a way to remove the message?
I came across this article yesterday while I was trying to find an answer for the exact problem described in the title. I was never able to find anything from any of the Google searches I ran. However, I was able to figure out what the problem was.
The issue is that when you save the PdfDocument object, it is defaulting the PDF as version 0. You can verify this by opening the generated PDF in Notepad++ (or similar text editor) and looking at the first line. When you open the PDF, Acrobat/Reader has to format it to be able to display it since it is an outdated PDF version; thus causing the document to be changed.
The solution is to set the Version of the PdfDocument before you save (an example of this can be seen here: https://forum.pdfsharp.net/viewtopic.php?f=2&t=617). As of PDFsharp version 1.50, the highest supported version is 17 (see PDFsharp Wiki on which PDF versions are supported).

iTextSharp, add barcode to page 1 after generating document

I am using iTextSharp (5.5.5.90) to generate PDF files. I am using paragraphs and importing pages from readers and such. Here is how I create my document, from there I just append what I need:
FileStream fs = new FileStream("filename.pdf", FileMode.Create, FileAccess.Write, FileShare.None);
Document doc = new Document(new Rectangle(PageSize.LETTER), 58, 58, 100, 50);
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
Once the file is created, I add paragraphs like this:
doc.Add(new Paragraph("Paragraph text"));
And import pages from readers like this:
writer.DirectContent.AddTemplate(writer.GetImportedPage(reader, page), 0, 0);
My question is how would I go back to page one after generating the entire document and add an element to page one? I will be adding a barcode (I know how to add barcodes, tables and such where I want them on the current page), but I don't know how to "go back" to page one to add an element.
Here is the full code, but you won't be able to compile it because of dependencies. Also, don't get caught up in the details of the full code, as this is a large project to create dynamically generated documents. https://pastebin.com/kABi7fzW
I can't attest as to the exactly calls to iTextSharp's as we approached our documentation quite differently; open a Word template, at the data as DataTables, etc., do a MailMerge, close and reopen and save as PDF. Sounds more involved but doesn't require the granular level of detail you're doing of creating the document paragraph by paragraph but it does allow the document generator to worry about content and not style placement (handled via Word, manually and external to the application).
From experience with iTextSharp, you'll have a lot of trouble trying to float an element on top of a section to insert the barcode. The document generation tool has an annoying tendency to not quite work in this scenario. We endured many weeks of back and forth with iTextSharp support and a version upgrade and still couldn't get it to behave properly in all scenarios.
As discussed in the comments and given how you've already written your code (I doubt you'll scrap all that code and start with a MailMerge unless you really, really have to), you'll need to insert a placeholder block that you can locate via iTextSharp's PdfBuilder api. I'd imagine that setting a bookmark location would likely be the easiest way.
If it's possible (preferable?) to have the barcode on a page of its own, then you already have the code needed to do this (circa line 324 in your pastebin link) with;
// create doc...
// reopen doc and get page count
doc.NewPage();
// add barcode with page count + 1
// save

iTextSharp generating pdfs, compiles and runs without error but no PDF appears

I've tried a number of different variations to output a very basic PDF from memory but all seem to return the same result, which is to say it doesn't actually return anything. The code compiles and runs without error but when VS finishes processing the code nothing happens.
I'm using VS2008 and iTextSharp v5.1.1
Does anyone have any suggestions please?
Here is my code in its current state:
MemoryStream ms = new MemoryStream();
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, ms);
writer.CloseStream = false;
doc.Open();
doc.Add(new Paragraph("Test Content"));
doc.Add(new Paragraph(DateTime.Now.ToString()));
doc.Close();
Response.ContentType = "application/pdf";
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
Response.OutputStream.Flush();
Response.OutputStream.Close();
ms.Close();
One thing that I learned early on, don't use GetBuffer(), use ToArray(). See this post:
iTextSharp-generated PDFs now cause Save dialog in Adobe Reader X
I found what was causing my issue, the code was in a button_click event where the button control was inside an ajax update panel, as soon as i moved the button outside of the update panel it worked perfectly. Not sure if this is a fundamental mistake on my part or a bug with update panels so I'm off to have a read about them.
#Mark Storer, I appreciate now that this wasn't an ITextSharp problem, however when I wrote this I believed it to be, apologies to all for the mistake.

Using iText (iTextSharp) to populate XFA form fields in PDF?

I need to populate XFA form fields in a PDF (created with Adobe LiveCycle Designer). We're attempting to use iText (actually iTextSharp with C#) to parse the PDF, populate the XFA fields and then save the modified PDF back out.
All the examples I can find with iText (very few iTextSharp examples) talk about modifying AcroForm fields. This PDF does NOT have AcroForm fields and uses XFA only.
Pointers to any non-standard resources would be helpful (I've already done the requisite Googling on the topic and haven't found anything useful).
Code examples here would be awesome from anyone who has actually done what I'm trying to do.
If you can get a data packet into the PDF, the XFA runtime in Acrobat would populate those fields with the data in the data packet.
If you want to see what one of these looks like, create a form in LiveCycle Designer (comes with Acrobat Pro), add some fields to it, and save it as a dynamic PDF. Open the form in Acrobat and type some values into the fields and save it.
Open the PDF with a tool that lets you peer at the PDF data and you'll find /Catalog/AcroForm/XFA a stream that has an <xfa:datasets> packet with the values you typed. That's what you'll need to create yourself and insert into the PDF.
The XDP spec includes a description of the data packet and the merge algorithm. You can find it here:
http://partners.adobe.com/public/developer/xml/index_arch.html
Alternately, you buy the LiveCycle server from Adobe which lets you do all this programmatically in a number of ways including through web service calls.
using (FileStream existingPdf = new FileStream("existing.pdf", FileMode.Open))
using (FileStream sourceXml = new FileStream("source.xml", FileMode.Open))
using (FileStream newPdf = new FileStream("new.pdf", FileMode.Create))
{
// Open existing PDF
PdfReader pdfReader = new PdfReader(existingPdf);
// PdfStamper, which will create
PdfStamper stamper = new PdfStamper(pdfReader, newPdf);
stamper.AcroFields.Xfa.FillXfaForm(sourceXml);
stamper.Close();
pdfReader.Close();
}
iTextSharp can work with XFA. To remove all doubts, please take a look at sample on iText website:
http://itextpdf.com/examples/iia.php?id=165
I have the same issue and I think I found the solution. I am using Powershell to inspect the pdf object.
Load the iTextSharp DLL.
Add-Type -Path "C:\Users\micah\Desktop\itextsharp.dll"
Load the PDF into a variable:
$PDF = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList "C:\Users\micah\Desktop\test.pdf"
Inspect this object:
$PDF.AcroFields.XFA.DomDocument.XDP.DataSets.Data.TopMostSubForm | Get-Member
What you SHOULD see, is that all your fields on your PDF are in this object as a property.
You can get a quick view of all your fields like this:
$PDF.AcroFields.XFA.DomDocument.XDP.DataSets.Data.TopMostSubForm | Select-Object -Property "*"
That should be the magic ticket. This location is both fields from the original form AND the XFA portion of the form.
It says that in the book because itext does not do this. Can you convert your PDF?

Categories

Resources