Reputation: 124
I have created EditTextField in PDF using iTextSharp library. I can able to set FieldName to EditTextField. I also want to set DataFormat to it. I will get XML file containing only FieldName and Value. So While merging Value to PDF Template, I want to check the DataFormat and according to that I want to convert the value and set.
I have added a EditTextField. I can able to add name to textfield. I want to add format (Like DateTime format) to TextField. So that next time I can able to fetch all the text fields from PDF and check the format and according to the format, I can able to set the data to it programmatically.
TextField _DOBtext = new TextField(pdfStamper.Writer,
new Rectangle(40, 670, 110, 650), "patient-dob");
_DOBtext.SetFormat("DateFormat", "mm/dd/yyyy"); // we want to set format like this.
pdfStamper.AddAnnotation(_DOBtext.GetTextField(), 1);
pdfStamper.Close();
And while processing the same PDF for filling data, we will first check the AcrofieldName, and logic is written below (its not working code)
var GetField = pdfStamper.Acrofields.Field.where(u=>u.Key == "patient-dob").FirstOrDefault();
var Format = GetField.GetFormat(); // we want like this feature
if (Format != null) {
if (Format.Type = "DateTime") {
value=string.Format(data, Format.FormatString));
stamper.AcroFields.SetField(fieldId, value); //fieldId = "patient-dob"
}
}
Please help me to Set and get the DataFormat
(ediit: add iTextSharp tag)
Upvotes: 4
Views: 4995
Reputation: 139
This worked for me (using iText7)
textBox.SetAdditionalAction(PdfName.F, iText.Kernel.Pdf.Action.PdfAction.CreateJavaScript("AFDate_FormatEx(\"yyyy-mm-dd\");"));
textBox.SetAdditionalAction(PdfName.K, iText.Kernel.Pdf.Action.PdfAction.CreateJavaScript("AFDate_KeystrokeEx(\"yyyy-mm-dd\");"));
thanks to the iText RUPS tool.
Upvotes: 0
Reputation: 55417
The reason that iText doesn't support something like SetFormat()
and GetFormat()
is because the PDF format doesn't support it.
You might notice, however, that Adobe Acrobat allows you to specify a field format. The way that they do this is via a JavaScript file that they ship with all of their products. If other PDF renderers (such as Chrome, Firefox or IE) support this I don't know. This JS file has a bunch of built-in functions that they can use for client-side validation and one of those function is AFDate_FormatEx()
. You can see how that lays out in a PDF in this screenshot:
You might have noticed my emphasis above on client-side validation. That's because this is JS which is optional in the spec and it isn't required when programmatically interacting with forms. However, if you are trying to mimic Adobe's product you might want to go down this path. You can programmatically retrieve these settings via something like:
var aditionalActions = reader.AcroFields.Fields["patient-dob"].GetWidget(0).GetAsDict(PdfName.AA);
And you can set it via something like SetAdditionalActions()
on your PdfFormField
.
This is probably a really fragile path but it might work for you.
However, for me I'd try something different and just hijack another field that I know that I'm not going to use. Looking through the spec I think I'd just pick something like /TM
which is just a string used for the field's name when exporting data (I think via FDF or HTTP POST).
var _DOBtext = new TextField(writer, new iTextSharp.text.Rectangle(0, 0, 110, 650), "patient-dob");
var tf = _DOBtext.GetTextField();
tf.MappingName = "patient-dob:date:mm/dd/yyyy";
And to retrieve it:
var mappingName = reader.AcroFields.Fields["patient-dob"].GetWidget(0).GetAsString(PdfName.TM);
You can come up with whatever format you want for this entry, as long as it makes sense to you. I'd recommend keeping the field's original name as part of it and then picking whatever delimiters work for you. The value should travel safely with the PDF regardless of the rendering application.
Upvotes: 3
Reputation: 926
Sometime ago I wrote a library to manage PDF AcroForm fillup.. this the a sample code from my fill function:
private string fill_form(string output_file)
{
using (PdfReader _pdfReader = new PdfReader(FormPath))
{
using (PdfStamper _pdfStamper = new PdfStamper(_pdfReader, new FileStream(output_file, FileMode.Create)))
{
_pdfStamper.AcroFields.GenerateAppearances = true;
foreach (var _field in _pdfStamper.AcroFields.Fields)
foreach (TemplateField _spField in _lstFields)
{
if (_field.Key.Equals(_spField.Name))
{
switch (_spField.Type )
{
case TemplateFieldType.Text:
_pdfStamper.AcroFields.SetField(_field.Key, _spField.Value);
break;
case TemplateFieldType.Checkbox:
//TODO: check Value field cannot be set != OnValue, Offvalue
if (_spField.Value == _spField.OnValue)
_pdfStamper.AcroFields.SetField(_field.Key, _spField.OnValue);
else
_pdfStamper.AcroFields.SetField(_field.Key, _spField.OffValue);
break;
}
}
}
_pdfStamper.FormFlattening = true;
}
}
return output_file;
}
As you can see in the inner loop I do something similar to your needs. Hope this helps.
Upvotes: 1