iText7 usage rights and Adobe Reader - c#

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

Related

ITextSharp stamper corrupting pdf

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.

C# iTextSharp: The process cannot access the file because it is being used by another process

I'm generating a pdf file from a template with iTextSharp, filling each field in this code portion:
PdfReader pdfReader = new PdfReader(templatePath);
try
{
using (FileStream newFileStream = new FileStream(newFilePath, FileMode.Create))
{
using (PdfStamper stamper = new PdfStamper(pdfReader, newFileStream))
{
// fill each field
AcroFields pdfFormFields = stamper.AcroFields;
foreach (KeyValuePair<string, string> entry in content)
{
if (!String.IsNullOrEmpty(entry.Value))
pdfFormFields.SetField(entry.Key, entry.Value);
}
//The below will make sure the fields are not editable in
//the output PDF.
stamper.FormFlattening = true;
stamper.Close();
}
}
}
finally
{
pdfReader.Close();
}
Everything goes fine, file looks ok, but when i try to reopen the file to merge it with some other files I've generated in a unique document i get this error:
2015-11-23 09:46:54,651||ERROR|UrbeWeb|System.IO.IOException: The process cannot access the file 'D:\Sviluppo\communitygov\MaxiAnagrafeImmobiliare\MaxiAnagrafeImmobiliare\cache\IMU\E124\admin\Stampe\Provvedimento_00223850306_2015_11_23_094654.pdf' because it is being used by another process.
Error occurs at this point
foreach (Documento item in docs)
{
string fileName = item.FilePath;
pdfReader = new PdfReader(fileName); // IOException
// some other operations ...
}
Edit: Using Process monitor as suggested I can see there is no close CloseFile operation as I would expect. Can this be the source of the issue?
I've been stuck on this for hours any help is really really appreciated.
Had the same issue with me. This helped a lot.
"You're problem is that you are writing to a file while you are also reading from it. Unlike some file types (JPG, PNG, etc) that "load" all of the data into memory, iTextSharp reads the data as a stream. You either need to use two files and swap them at the end or you can force iTextSharp to "load" the first file by binding your PdfReader to a byte array of the file."
PdfReader reader = new PdfReader(System.IO.File.ReadAllBytes(filePath));
Ref: Cris Haas answer to Cannot access the file because it is being used by another process
I had a similar problem with opening pdf files (for read only) with iTextSharp PdfReader. The first file gave no problem, the second one gave that exception (can not access the file, etc.).
After hours and googling and searching for complicate solutions and twisting my brain, only the simple following code resolved it fully:
iTextSharp_pdf.PdfReader pdfReader = null;
pdfReader = new iTextSharp_pdf.PdfReader(fileName);

Encrypt PDF document using iTextSharp

I want to make my PDF document protected by not allowing fill in and copy from it. I am using iTextSharp for this. I have following code:
PdfReader reader = new PdfReader(document, System.Text.Encoding.UTF8.GetBytes(PASSWORD));
using (MemoryStream ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, ms))
{
stamper.SetEncryption(
null,
Encoding.ASCII.GetBytes(PASSWORD),
PdfWriter.ALLOW_PRINTING,
PdfWriter.ENCRYPTION_AES_128);
}
}
reader.Close();
When the document is generated I use that code to encrypt the document. But later when I open the document in Adobe Reader (tested on 9 and 11) and check the 'File > Properties > Security' their are no restrictions applied on fill in and copy of the document and their status is Allowed.
Is there any issue in that code?
According to the ITextSharp documentation for PdfStamper, the second parameter to this method is an output stream representing the destination for the encrypted PDF document data. The code you show in the question simply disposes the MemoryStream after you setup the encryption so any changes this code could apply to your PDF document will never be saved to disk or otherwise be available outside your application.

Disable extended features with iTextSharp

I have a PDF template with a form with the Extended features enabled. After filling in the fields of this form using iTextSharp, a user with acrobat reader gets the error message:
This document enabled extended features in Adobe Reader. The document has
been changed since it was created and use of extended features is no longer
available. Please contact the author for the original version of this
document.
I googled a bit but all the posts talk about "enabling" extended features, however, I want the form fields to remain disabled and extended features turned off
Here a sample code which I am using:
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
// Open existing PDF
var pdfReader = new PdfReader(existingFileStream);
// PdfStamper, which will create
var stamper = new PdfStamper(pdfReader, newFileStream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
if (fieldKey.Equals("Retailer Name"))
form.SetField(fieldKey, retailerName);
}
// “Flatten” the form so it wont be editable/usable anymore
stamper.FormFlattening = true;
stamper.Close();
pdfReader.Close();
}
The links here are dead as the iTextPdf web site has been completely revamped. But the answer can be understood without those links, too.
The iText Keyword: Reader enabled PDFs points to the following information:
Submitted by Bruno Lowagie on Fri, 12/31/2010 - 16:37
After filling out my form, my PDF shows the following message: This document enabled extended features in Adobe Reader. The document has been changed since it was created and use of extended features is no longer available. Please contact the author for the original version of this document. How do I avoid this message?
The creator of the form made the document Reader enabled. Reader enabling can only be done using Adobe software. You can avoid this message in two ways:
Remove the usage rights. This will result in a form that is no longer Reader enabled. For instance: if the creator of the document allowed that the filled out form could be saved locally, this will no longer be possible after removing the usage rights.
Fill out the form in append mode. This will result in a bigger file size, but Reader enabling will be preserved.
It also points to the sample ReaderEnabledForm.java (the C#/iTextSharp equivalent of which is ReaderEnabledForm.cs) which shows how to do either.
In your case this amounts to calling
pdfReader.RemoveUsageRights();
right after creating the PdfReader and before creating the PdfStamper.
/**
* Removes any usage rights that this PDF may have. Only Adobe can grant usage rights
* and any PDF modification with iText will invalidate them. Invalidated usage rights may
* confuse Acrobat and it's advisabe to remove them altogether.
*/
public void RemoveUsageRights()
Fill out the form in append mode by using the PdfStamper constractor overload
// PdfStamper, which will create
var stamper = new PdfStamper(pdfReader, fileStream, '\0', true);

Fill PDF Form with Itextsharp

I am trying to fill up a form with ITextsharp, and trying out the following code to get all the fields in the pdf:
string pdfTemplate = #"c:\Temp\questionnaire.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
StringBuilder sb = new StringBuilder();
foreach (var de in pdfReader.AcroFields.Fields)
{
sb.Append(de.Key.ToString() + Environment.NewLine);
}
But the foreach loop is always null count. Do I need to do something to file itself as I have tried the example from here and it works fine... this is an example of pdf I am trying to fill
any ideas?
Edit ::
As it turned out, the PDF "form" to fill in actually wasn't a form (in PDF terms) at all. Thus, your have two choices:
You add the text to the page contents directly using hardcoded or configured "field" positions and dimensions as described by #tschmit007 in comments to his answer.
You add actual PDF form fields to your PDF to generate a true PDF form which you take as template to fill in later.
You can add actual form fields either using some graphical tool allowing that, e.g. Adobe Acrobat, or you can use iText(Sharp). Have a look at chapter 8 of iText in Action — 2nd Edition and the samples available here for Java and here for .Net.
Those samples mostly add form fields to newly generated PDF documents. You can virtually use the same code, though, for adding form fields to a PdfStamper which exposes its inner PdfWriter using stamper.getWriter() in Java and the stamper.Writer in C#. Instead of writer.addAnnotation(field) you have to use stamper.addAnnotation(field, page), though.
try:
using (FileStream outFile = new FileStream("result.pdf", FileMode.Create)) {
PdfReader pdfReader = new PdfReader("file.pdf");
PdfStamper pdfStamper = new PdfStamper(pdfReader, outFile);
AcroFields fields = pdfStamper.AcroFields;
//rest of the code here
//fields.SetField("n°1", "value");
//...
pdfStamper.Close();
pdfReader.Close();
}

Categories

Resources