I'm trying check a checkbox on my PDF with iText7.
But instead of checking only one field, it's checking all fields
What I need:
What I get:
PDF when editing:
I think the exported value has something to do with it.
But I don't kown what to do.
My code:
private static void CreatePdf(string output)
{
using var _pdfDoc = new PdfDocument(new PdfReader("CheckTest.pdf"), new PdfWriter(output));
var form = PdfAcroForm.GetAcroForm(_pdfDoc, true);
var check = form.GetField("Check");
check.SetValue("01");
}
PDF: Link
Someone know how to check it properly?
Thanks!
First of all, the PDF essentially mis-uses PDF AcroForm check box fields as radio buttons instead of using genuine PDF AcroForm radio button fields.
The PDF specification does not clearly specify what a PDF viewer should do in such a case (it's mis-use after all) but the developers of the PDF form generator in question probably have experimented and determined that in the most widely used PDF viewer, Adobe Acrobat Reader, this mis-use works just as they want.
As this use is beyond specification, though, other PDF processors processing such PDFs may produce completely different results without doing anything wrong.
That being said, there is a way to fill the form using iText and achieve results similar to those generated by Adobe Reader.
The problem at hand is that iText by default for all form field types except actual AcroForm radio button fields generates new appearances in a way appropriate for the field type when setting the field value. In your document there are three check box field objects with the same name. Thus, they are considered a single check box with three widgets representing the same value, and so the appearances are generated as you observe.
But you can tell iText to not generate new appearances, using another SetValue overload accepting an additional boolean value, simply replace
check.SetValue("01");
by
check.SetValue("01", false);
Now iText makes do with the existing appearances, so only the field becomes checked that has an appearance for that "01" value.
Beware, only prevent iText from generating appearances in cases like this. In case of text fields, for example, not updating the appearances would cause the old appearances with the former field content to continue to be displayed even though the internal field value changed.
A did it like this:
Dim MyPDFFormCheckBoxField As Fields.PdfFormField = myform.GetField("myCheckBox")
MyPDFFormCheckBoxField.SetCheckType(PdfFormField.TYPE_CHECK)
MyPDFFormCheckBoxField.SetValue("", If(myCheckBox.IsChecked = True, True, False))
Notice that it is the second parameter of SetValue that is setting the checkbox True or False.
Related
I have a secured PDF Template with editable fields. When I set a field's value it doesn't show up until I click on it and modify it.
Code for inserting a value into a field:
static void Main(string[] args)
{
using (PdfReader reader = new PdfReader(desktopPath + "PdfTemplate.pdf"))
{
reader.SetUnethicalReading(true);
using (PdfDocument pdfDocument = new PdfDocument(reader, new PdfWriter(desktopPath + "ModifiedPdfTemplate.pdf")))
{
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDocument, true);
IDictionary<string, PdfFormField> fields = form.GetFormFields();
fields["Date"].SetValue("DATE");
}
}
}
This is what an unedited field looks like:
After I run the code, the field still looks like before, but there is a value if I click on it:
After I modified the field (added a space at the end), now it shows the text:
I think it's because there is some styling on the field. How can I achieve that is shown on the last picture?
Software Versions:
Itext -> 7.1.16
Adobe Acrobat -> 2020.009.20063
After the attempt to reproduce the issue here failed, the next step was comparing versions of software involved.
Synchronizing the iText version to the current 7.1.16 still resulted in different observations.
But then updating the PDF viewer, Adobe Acrobat (Reader), finally resolved the issue.
Apparently Acrobat 2020.009.20063 fails to display the field properly while Acrobat 2021.001.20155 and 2021.007.20091 succeed.
(One might think that basic functionality like field value showing should have been stable in Acrobat for a number of years. But apparently changes do still occur here. This may be related to hardening of signed forms against forgery in the recent months and years.)
I also faced the same issue, It was due to the font of the Form field, set the font value to null while creating the field or update the font of the existing field.
if the font is null Itext will use the document's default font
I am trying here to create a piece of code which would open an existing PDF Form (previously created with Open Office) with empty controls and set the values using iTextSharp (). I am still at the testing of iTextSharp to see if it does whatever I need to do, and so far the answer is no.
Please see what I've done below according to what I found on the net:
string fileNameExisting = #"PdfTemplate.pdf";
string fileNameNew = #"new.pdf";
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)
{
bool result = form.SetField(fieldKey, "A lot of text here.");
}
stamper.Close();
pdfReader.Close();
}
Issue 1
iTextSharp only recognizes 'controls' elements from Open Office (Textboxes for example). I tried to add a table to the PDF Template but it doesn't appear in the fields. Which means I am really limited in what to use.
Issue 2
When I set the text in the fields, there is no wraping of the text, and the size of the controls is not dynamic which means if the text is too long, it doesn't all appear. I can't use the scroll bar as the PDF is to print.
I tried
For the first issue, I created a PDF Form with Word instead of Open Office Writer. However, iTextSharp does not recognize any of the controls from Word, my fields collection is empty..
For the second issue, I tried to modify every properties of the controls in Open Office, looked on the internet to see if someone had a solution. But from what I understood, the size is fixed as it is AcroFields, so I can't make the control dynamic and can't change the size afterwards with iTextSharp.
I was hoping someone went through the same situation and would be able to guide me either with iTextSharp, or another library, free or not. I can't afford a £2000 license though as I am running my own business, but I am open to suggestions as I need to deliver.
The last option is to create the PDF from scratch with iTextSharp, but it's not as fast and easy to produce as the modification, and it means that for every update of the PDF, the company would need me to change the code... I'm not very pleased with that solution.
Issue 1:
A table is not a form field. Please read the PDF specification, more specifically ISO-32000-1:
There is no such thing as a dynamic table in PDF. That is only possible in XFA (which is XML wrapped in a PDF file), but XFA is being deprecated. At iText, we'll release a (closed source) product in February 2017 for dynamic documents.
Issue 2:
The text only wraps if the field is defined as a multi-line text field. See for instance https://developers.itextpdf.com/question/how-get-row-count-multiline-field
The font size only adapts to the size of the field if you set the font size to 0: Set AcroField Text Size to Auto
Summarized:
Dynamic forms and PDF either require XFA in which case you need to buy Adobe LiveCycle ES (which is way above your budget), or you need to wait until iText Group releases its dynamics forms project (but that will also be more expensive than £2000).
Is it possible to modify spot color names in a PDF using iTextSharp in C#, its just the Colour name that requires changing.
So you have an existing PDF that uses some spot colors, for instance a color named "ABC", and you want to manipulate that PDF so that the name is "XYZ".
This is possible, but it requires low-level PDF syntax manipulation.
You need to create a PdfReader instance, look for the dictionary that defines the spot color, change the name, then use PdfStamper to create a new file based on the altered PdfReader instance.
There is no "ready-made" example on how to answer your specific question (I doubt somebody else but the original developer of iText will answer a question like this), but you can get some inspiration by looking at the code samples from chapter 13 of the second edition of "iText in Action": http://itextpdf.com/book/chapter.php?id=13
See for instance the manipulatePdf() method in this example: http://itextpdf.com/examples/iia.php?id=239
In this example an URL is replaced by another one using the principle explained above.
You need to adapt this example so that you find the path to the place where the spot color name is stored, change that name, and persist the changes.
Hint: the Spot color name will be in an array of which the first element is a name (/Separation), the second entry will be the name you want to change (this is the one you want to replace with a new PdfName instance), and so on.
How to find this /Separation array? I would loop over the pages (the getPageN() method will give you the page dictionary), get the resources of every page (pageDict.getAsDict(PdfName.RESOURCES)), look for the existence of a /Colorspace dictionary, then look for all the /Separation colors in that dictionary. Replace the second element whenever you encounter a name you want to change.
The examples in chapter 13 in combination with ISO-32000-1 (can be downloaded from the Adobe.com site) will lead the way.
I have a pdf with a form in it. I am trying to write a class that will take data from my database and automatically populate the fields in the form.
I have already tried ITextSharp and their pricing is out of my budget, even though it works perfectly fine with my pdf. I need a free pdf parser that will let me import the pdf, set the data, and save the PDF out, preferably to a stream so that I can return a Stream object from my class rather than saving the pdf to the server.
I found this pdf reader and it doesn't work. Null reference errors are abundant and when I tried to "fix" them, it still couldn't find my fields.
So, I have moved on to PdfBox, as the documentation says it can manipulate a PDF, however, I cannot find any examples. Here is the code I have so far.
var document = PDDocument.load(inputPdf);
var catalog = document.getDocumentCatalog();
var form = catalog.getAcroForm();
form.getField("MY_FIELD").setValue("Test Value");
document.save("some location on my hard drive");
document.close();
The problem is that catalog.getAcroForm() is returning a null, so I can't access the fields. Does anyone know how I can use PdfBox to alter the field values and save the thing back out?
EDIT:
I did find this example, which is pretty much what I am doing. It's just that my acroform is null in pdfbox. I know there is one there because itextsharp can pull it out just fine.
Have you tried with the 1.2.1 version?
http://pdfbox.apache.org/apidocs/overview-summary.html
I have a PDF form with a number of text fields. The values entered in these fields are used to calculate values in other fields (the calculated fields are read-only).
When I open the form in Adobe Reader and fill in a field, the calculated fields automatically re-calculate.
However, I am using iTextSharp to fill in the fields, flatten the resulting form, then stream the flattened form back to the user over the web.
That part works just fine except the calculated fields never calculate. I'm assuming that since no user triggered events (like keydowns or focus or blur) are firing, the calculations don't occur.
Obviously, I could remove the calculations from the fillable form and do them all on the server as I am filling the fields, but I'd like the fillable form to be usable by humans as well as the server.
Does anyone know how to force the calculations?
EDIT:
I ain't feeling too much iText/iTextSharp love here...
Here are a few more details. Setting stamper.AcroFields.GenerateAppearances to true doesn't help.
I think the answer lies somewhere in the page actions, but I don't know how to trigger it...
Paulo Soares (one of the main devs of iText and current maintainer of iTextSharp) says:
iText doesn't do any effort to fix
calculated fields because most of the
times that's impossible. PdfCopyFields
has some support for it that sometimes
works and sometimes don't.
I have updated all the calculated fields of my pdfs by calling the javascript method calculateNow on the Doc object.
According to the adobe javascript documentation this.calculateNow();
Forces computation of all calculation fields in the current document.
When a form contains many calculations, there can be a significant delay after the user inputs data into a field, even if it is not a calculation field. One strategy is to turn off calculations at some point and turn them back on later (see example).
To include the javascript call with iTextSharp :
using (PdfReader pdfReader = new PdfReader(pdfTemplate))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create)))
{
// fill f1 field and more...
AcroFields pdfFormFields = pdfStamper.AcroFields;
pdfFormFields.SetField("f1", "100");
//...
// add javascript on load event of the pdf
pdfStamper.JavaScript = "this.calculateNow();";
pdfStamper.Close();
}
I have figured out how to do this. Please see my answer for the stackoverflow question:
How to refresh Formatting on Non-Calculated field and refresh Calculated fields in Fillable PDF form
On the server side, see if there is an answer in the calculated fields. If not, calculate them.
As Greg Hurlman says, you should do the calculations yourself on the server. This is for more than just convenience, there's actually a good reason for it.
Any file that the customer has, they have the potential to screw with. I don't know what the PDF forms are for, but chances are it's connected to money somehow, so the potential exists for people to cheat by making the calculations show the wrong result. If you trust the calculations done on the client side, you have no way of detecting it.
When you recieve the PDF form from the client, you should redo all calculations so that you know they're correct. Then if you also have the client's versions to compare to, you should check whether they've been screwed with.
Don't think your clients are that untrustworthy? Good for you, but the evidence disagrees. One of my earliest introductions to programming was opening up the savegames for SimCity to give myself more money. If the opportunity exists to cheat in some way, then at some point people will try it.