Using the iText PDF libraries (v7), does anyone have any advice on how to remove 'Document-level' JavaScripts from PDFs? I have figured out how to remove Page-Level JavaScripts, but cannot seem to figure out how to remove those at the document-level. Thank you.
I got this resolved and below is the snippet of code (C#) in case anyone else needs it:
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SOURCE), new PdfWriter(TARGET));
PdfCatalog pdfCat = pdfDoc.GetCatalog();
PdfDictionary names = pdfCat.GetPdfObject().GetAsDictionary(PdfName.Names);
names.Remove(PdfName.JavaScript);
pdfDoc.Close();
Related
I have searched and searched and cannot find the answer to my problem. I've tried many different approaches in my code, but I've hit a wall and I'm not sure where to go from here. I seem to be wanting to do the same thing as these two threads:
Trying to insert an image into a pdf in c#
Add image in an existing PDF with itextsharp
They are very similar and the answer is the same. However, when I use that exact code, the result is a PDF without an image. Here is my code:
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, newFileStream, '\0', true);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (var field in form.Fields)
{
if (field.Key == "form1[0].ec_Bldg_Photo_1[0].ImageField2[0]")
{
PushbuttonField imageField = form.GetNewPushbuttonFromField(field.Key);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.IconReference = null;
imageField.ProportionalIcon = true;
imageField.Image = Image.GetInstance(#"PATH_TO_IMAGE\front.jpg");
form.ReplacePushbuttonField(field.Key, imageField.Field);
}
}
stamper.FormFlattening = false;
stamper.Close();
pdfReader.Close();
}
I have tried to rule out all of the obvious things. My path to the image is correct, the field is indeed a PushbuttonField when I read the existing PDF field and get the field type. If I open the PDF in Adobe Reader and click on the placeholder for the image, it allows me to pick a file from my PC. When I place an image in the file, save, and then read in that PDF, I can then change my code to this:
imageField.ProportionalIcon = false;
And now all of sudden the image is stretched on the saved copy. So I see that it is changing this part but this is when I enter the image manually in Adobe Reader. When I read in the field after I set that image in Adobe Reader and it shows correctly, I see a couple interesting things. The field.Image property IS NULL and the field.IconReference is NOT NULL. When I use the original code to try and insert the image, it is reversed, where Image is NOT NULL but IconReference IS NULL
Any help would be greatly appreciated, thank you!!
EDIT 1: Ok so I didn't see it the first time, but I went back and checked more thoroughly and I did find that key. Here it is:
Several things are at play here.
Usage Rights:
The PDF is digitally signed with a private key owned by Adobe.
You can see this using RUPS here (in your screen shot you didn't go deep enough):
This has two implications:
The signature unlocks special permissions in Adobe Reader, such as the permission to save a filled out form locally.
Making any changes to the original PDF breaks the signature and removes the special permissions leading to an ugly error message in Adobe Reader.
This functionality is deprecated in (and even removed from) PDF 2.0. It's old technology that became obsolete with the emergence of PDF viewers other than Adobe Reader.
My suggestion: remove the usage rights to avoid breaking the signature. See the FAQ entry "Why do I get an error saying that "use of extended features is no longer available"?" iText 7 / iText 5
This is the iText 7 code:
public void removeUsageRights(PdfDocument pdfDoc) {
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
if (perms == null) {
return;
}
perms.remove(new PdfName("UR"));
perms.remove(PdfName.UR3);
if (perms.size() == 0) {
pdfDoc.getCatalog().remove(PdfName.Perms);
}
}
This is the iText 5 code:
PdfReader reader = new PdfReader(old_file);
if (reader.hasUsageRights()) {
reader.removeUsageRights();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new_file));
stamper.close();
}
reader.close();
This is the iText 5 answer.
Hybrid Form:
If you click on the /AcroForm entry, you see this:
There is a /Fields array with references to field dictionaries that are also widget annotations. That means that the document has an AcroForm form inside. However, there is also an /XFA entry with a series of XML snippets. That means that the document has an XFA form inside.
In other words: the same form description is added twice inside. You are changing a button in one form (the AcroForm part), but not in the other (the XFA form) and that leads to inconsistencies.
XFA has been deprecated in PDF 2.0 because there weren't many vendors supporting that technology. It's kind of frustrating to be confronted with forms that use deprecated technology.
My suggestion: I would remove the XFA part. See the FAQ entry "Is it safe to remove XFA?" iText 5 / iText 7
In iText 5, removing XFA is done like this:
AcroFields form = stamper.getAcroFields();
form.removeXfa();
Important: my suggestion is to remove all the deprecated functionality from the PDF, but if the government expects that functionality to be present, then you're out of luck. In that case, you will need to use Adobe software to process the form. If that's the case, you could complain to the government that their requirements lead to a de facto vendor lock-in. By the way: iText Software is also a vendor. It's an open source company that offers open source software under the AGPL license. The AGPL license allows free use under certain circumstances (see How do I make sure my software complies with AGPL: How can I use iText for free?) If you don't meet those requirements, you will have to purchase a commercial license for your use of iText.
I am trying to convert a word document(.docx) into PDF. I am trying to pass Stream object into load document method of RichEditDocumentServer,but my bad ,I am getting a blank pdf. I tried passing the file path in load document method ,which worked fine. But my requirement has to meet with stream object. Can anyone help me to fix the issue. A sample code has been added below.
private Stream ConvertToPdf(Stream fileStream)
{
RichEditDocumentServer server = new RichEditDocumentServer();
fileStream.Seek(0, SeekOrigin.Begin);
server.LoadDocument(fileStream, DocumentFormat.Doc);
Stream convertStream = new MemoryStream();
server.ExportToPdf(convertStream);
convertStream.Seek(0, SeekOrigin.Begin);
return convertStream;
}
it worked with the below link
https://www.devexpress.com/support/center/Question/Details/T340655#answer-9c3224dd-383a-4faa-9672-9b34e36c1c7a
server.LoadDocument(fileStream, DocumentFormat.OpenXml);
While upgrading from iText 2.1.3 to iText 2.1.7 I noticed a change in behavior. The input PDF file is coming from Adobe Indesign and the goal is to change the Application and PDFProducer properties to something I want.
Below is the relevant piece of code :
PdfStamper pdfStamper = null;
PdfReader pdfReader = null;
pdfReader = new PdfReader(new RandomAccessFileOrArray(source), null);
HashMap info = pdfReader.getInfo();
info.put( "Producer", "Myself");
info.put( "Creator", "Myself");
OutputStream outputStream = new FileOutputStream(source+"stamped.pdf");
pdfStamper = new PdfStamper(pdfReader, outputStream, '\0', true); // append mode
pdfStamper.close();
pdfReader.close();
So, before, using itext 2.1.3, after running a pdf through the code above, I would see the Application and PDFProducer changed to "Myself" when opening the file in Adobe Reader (File, Properties). That's what I expect
With itext 2.1.7, the Application property does not change and the PDFProducer property has the text "modified using iText 2.1.7 by ..." appended.
Using iText 5.4.5, the Application property is changed but the PDFProducer update behaves just like in 2.1.7
Any idea what happened and if there is something I can do to fix this?
thanks
Cristian
If you do a google search you will find some code samples more or less like this:
PdfWriter writer = PdfWriter.GetInstance(document, myIoStream);
And interestingly, most of the code samples don't use the writer object at all. So, what's the point of getting that handle? Thank you!
You can do just PdfWriter.getInstance(document, myIoStream);
this will "create" the document using the stream.
When using PdfWriter writer = PdfWriter.GetInstance(document, myIoStream);
we can use a lot of methods like AddAnnotation() that will be merged with the document or also call .DirectContent to add images, etc.
Hope it helps.
I am working in asp .net mvc3.
I have these statements in controller class:
PdfWriter.GetInstance(doc, new FileStream((Request.PhysicalApplicationPath + "\\Receipt5.pdf"),
FileMode.Create));
doc.Open();
PdfPTable table = new PdfPTable(2);
table.AddCell("tt[0]");
table.AddCell("tt[1]");
doc.close();
All time my values are changing but in pdf sometimes showing old result. please tell me what should i do for it that whenever i press done button then new pdf document should generate.
i am using iTextSharp to generate pdf.
It seems that you're not able to replace the old file cause it is locked.
Try to delete it and see what happens.
Anyway, consider that if more than one user tries to print the same document you can have a concurrency problem.
I would suggest you to use a generated file name:
var newFile = System.IO.Path.Combine(Request.PhysicalApplicationPath, Guid.NewGuid().ToString() + ".pdf");