I know there are many similar questions on here, i've tried several of them but have not managed to solve the problem(and many of them are still unanswered after several years).
My problem is that i can not set the value of the two fields at the top of the second page named "form1[0].sida2[0].flt_datSidhuvud[0]" and "form1[0].sida2[0].flt_txtPersonNrBrukare[0]", they both have a field with same name but different prefix on the first page and from the research i've done this might be causing the problem but the suggested solutions have not worked for me.
If i fill in the form manually with for example Acrobat Reader the values that are input in the fields on page one automatically appear in the fields on page two and the other way around.
Here is an example of the code i use to try and fill in the two fields
MemoryStream output = new MemoryStream();
FileStream fs = File.Open(pdfTemplatePath, FileMode.Open, FileAccess.Read);
PdfReader reader = new PdfReader(fs);
fs.Close();
PdfStamper stamper = new PdfStamper(reader, output);
var formFields = stamper.AcroFields;
formFields.SetField("form1[0].sida2[0].flt_datSidhuvud[0]", "2016-12"));
formFields.SetField("form1[0].sida2[0].flt_txtPersonNrBrukare[0]", data.SocialSecurityNumber);//data.SocialSecurityNumber is a string
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
The result is that it fills in the value of the fields on the first page only.
Link to PDF
From my research this question here on SO was the most promising but the suggested solution(to remove XFA) doesn't seem to work in my case.
In general
If (AcroForm) form fields have different full names, they are separate fields.
A behavior as you describe (filling one field in Adobe Reader upon losing focus automatically fills another one, too) can be achieved using JavaScript actions. But filling in these fields using iText does not trigger any JavaScript events. Thus, in general you have to fill in both (AcroForm) fields.
Your case is special
Your case is slightly different, though:
Your PDF contains a hybrid form, both present as AcroForm form and as XFA form, and iText sometimes in the 5.x versions got fitted with a certain amount of XFA support. In particular in case of hybrid forms,
whenever the value of a field is retrieved, it first is looked up in the XFA form data elements; and
whenever a field value is set, it is set both in a single matching AcroForm field and in the XFA form data elements.
In the AcroForm representation of your form, the flt_datSidhuvud and flt_txtPersonNrBrukare fields on page 2 (which you do not explicitly fill) are empty and don't even have an appearance stream.
In the XFA representation of your form both flt_datSidhuvud form fields are backed by a single data element, and so are both flt_txtPersonNrBrukare form fields.
Furthermore, your case is special because you flatten the form. If you did not flatten id, only the values in the fields of the AcroForm fields on the first page and the XFA data fields would be set, not the AcroForm fields on the second page.
Form flattening has also been substantially improved during the 5.x versions.
Why does it work
While flattening your hybrid form, the fields on page two get their values:
While flattening the still empty flt_datSidhuvud and flt_txtPersonNrBrukare AcroForm fields on page two, iText determines that they do not have any appearance streams yet to flatten into the page content and, therefore, tries to create appearance streams for them.
To create these appearances, iText first retrieves the value of each field. As mentioned above, this means that the value in the XFA form is looked up first which is the same for both the fields on page one and two. Thus, here the value you set for the field on the first page is retrieved and used for building the appearance on the second page!
Why didn't it work for you initially
In comments you said that you mostly used the older 4.1.6.0 iTextSharp version, not the current 5.5.11.0 one. As explained above, the automatic fill-in on your second page depends on the iText XFA support and form flattening improvements both of which were introduced during the 5.x versions.
Thus, your initial attempts to run the code from your question did not result in filled-in fields on page 2 because the older iTextSharp versions simply did not implement support for that.
Related
Me and my team recently changed from ITextSharp to PdfSharp, because of ITextSharp became really slow, and we couldn't seem to fix the problem.
But right now we have a problem, where our pdf, thats filled by PdfSharp, is 200kb bigger then the one from ITextSharp. The size itself isn't the problem, its that when we open our pdf in firefox, the data is still displayed fine in the viewer, but when we want to print it, all the multiline fields, is suddenly one liners, with a different font too.
We have /NeedAppearance on our acroform elements, and tried to remove it to see what it would look like in adobe, and etc. and it looked the same as it did on the print screen in firefox.
The NeedAppearance isn't on our document from the ITextSharp, and it displays fine in every viewer.
This is the code we use to set the text:
public static bool SetField(this PdfAcroForm form, string fieldName, string value)
{
PdfTextField field = (PdfTextField)form.Fields[fieldName];
if (field != null)
{
field.Text = value;
}
return field != null;
}
At the end of the fields being set, we have a document.flatten() to make the fields readOnly.
A little side note
Once we have opened the pdf in adobe, and we want to close it, it wants us to save it, without we have changed the document. Once we have saved it, it is 200kb less, and suddenly works in all viewers. This is with /NeedAppearance on.
Update 1
I've spend the whole night looking for a solution, but couldn't.
But this is what I have found so far:
On every PdfTextField after the Text property has been set, there comes an /AP element in Elements which contains a reference to an object, which contains what should be drawn.
I think that Adobe can understand the /NeedAppearance element on the acroforms, and therefore makes the /APelement on every field correct. The reason for the file is less kb after, is seams to be that Adobe do something with the streams on the elements, some sort of encoding, that takes off less space.
So as it is right now, I think I have too create a new Flatten method that creates the /AP elements right. I don't know why The current Flatten method doesn't do that, as it's only changing the fields to readonly.
What I ended up doing, is to create my own flatten method.
Summary of what the Flatten method do:
I've mad it an extension to PdfAcroForm.
I loop trough all the fields, except PdfChecboxfield, because that is displayed just fine.
Then I went and found the page the field was on, and created and XGraphics from that page.
Then I get the position and size of the field, from the element /Rect
Then putted my XGraphics in a XTextFormatter, and sets the appearance on my XTextFormmater by the elements of my field.
Then I use XTextFormatter.Drawstring() and after that, dispose my XGraphics.
Then to remove the field, I delete all the elements on that field.
If this was unclear to you, feel free to comment, and I'll try my best to help you.
DISCLAIMER:
The flatten method I created, will delete your fields, and you CAN NOT undo it. It writes the text on the pdf itself, but just do it on the fields position.
Acrobat DC, Office 365, iTextSharp5, Win10 Pro 64-bit
I have a Word document containing several pages of text and one empty TextBox in between two of the lines. I am attempting to use the Acrobat "Prepare Form" feature to convert that document to PDF with the TextBox as a fillable field, and Acrobat has no problem auto detecting the TextBox and making it fillable. The problem, however, is that the converted TextBox contains text from either the line of text above it or below it.
I've read that this is caused by placing the TextBox too close to those lines in the Word document and sure enough, by leaving three or four empty lines of space above and below the text box the issue goes away. However, that's an unacceptable amount of wasted space. I tried putting continuous section breaks above and below the TextBox in Word as well as typing spaces in the TextBox but that doesn't help. I also tried it with a 1x1 table instead of a TextBox but the same problem occurred.
I then tried deleting the unwanted text from the PDF TextBox field and saving it that way, which appeared to be a reasonable solution. However, when I used an iTextSharp5 program to detect the PDF's fillable fields it could no longer detect the empty field. I wouldn't mind leaving the original unwanted text in the PDF TextBox field if there were some way to remove it with iTextSharp, but it doesn't seem to have that ability.
Because I have many Word documents to convert to fillable PDF's and might need to update them occasionally, it simply isn't practical for me to manually add the fillable fields to the converted PDFs each time an update is needed. Any suggestions are welcome :-)
I am having the exact same problem described here. Unfortunately because I don't have 50 points yet I can't comment on it so I have to create a new duplicate question.
I mean it's not "100% EXACTLY" like the other guy's problem because for me the problem exists on the Edit Form and I'm using a combination of custom forms and fields. But I am adding the custom save event handler at the field level per suggestion #2 made by the guy at this site. I should also note that when I create a new Document Library without any custom forms or Content Types and just use my custom fields straight-up, the event handler also does not fire. If however I create a new regular SharePoint list and add the custom fields then the OnSaveHandler DOES fire! I So I'm not quite sure why it doesn't work in Document Libraries but it does work in lists because I was under the impression that the beauty of custom fields was that they operate independently of everything else. Meaning, even if I was doing something wonky with my Edit Form or some other control, since I am attaching my custom method to the SPContext.Current.FormContext.OnSaveHandler in the OnInit method of my custom field then that should fire no matter what! Even when the field is being loaded for the first time I actually see the event being wired up in the debugger. In debug mode I have a breakpoint next to the "if" statement below and it hits that breakpoint which means that when the FormContext.OnSaveHandler is triggered my method should fire.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if ((SPContext.Current.FormContext.FormMode == SPControlMode.New) || (SPContext.Current.FormContext.FormMode == SPControlMode.Edit))
SPContext.Current.FormContext.OnSaveHandler += new EventHandler(MyHandler);
}
Any thoughts? Suggestions?
Thanks!
UPDATE #1: After a little troubleshooting I was able to deduce that the EventHandler in my custom field was being fired but ONLY when used in regular lists and NOT Document Libraries! In regular SharePoint lists not only is the SPContext.Current.FormContext.OnSaveHandler being fired but the values from the custom fields are being saved as well.
As a side note, when saving the data back to my custom field that inherits from SPFieldText, the value (which is json data) displays in the list view as #VALUE!, which I think is kind of weird. I mean it's able to read the json data that's stored in the field correctly because it shows up in the Edit Form just fine. But for some reason SharePoint just displays it as #VALUE! in the list view.
So after many frustrating hours it looks like there are several issues that arise when using custom fields in a Document Library.
You can't use them in any meaningful way and expect the data to be saved when using a custom upload page. In other words, if you want to create your own custom upload page that combines the file upload input field and browse button along with your own custom fields embedded in a ListFieldIterator then the values WILL NOT BE SAVED. This is a fact! The reason is that the operation for uploading the file and creating the initial ListItem along with generating it's ID value occurs ASYNCHRONOUSLY with respect to the ListItem EventReceiver. So what does this mean exactly? It means that when you try to access the values stored in your custom field(s) in the SPItemEventProperties parameter of the ItemAdded method in the ListItem's Event Receiver all of those values will be null since the current SPContext is completely unaware of the existence of those fields and their respective values because all of the events that occur with respect to the initial document upload are executed in a different thread...asynchronously. Conversely, when the custom fields attempt to "save themselves" back to the newly uploaded document the SPField.ListItem's document ID is still set to zero because these custom fields are...you guessed it, executing in a different thread and are not "in synch" with the upload event that took place which generated the new document ID. Although I've read about a few different workarounds regarding this issue, none of them seem to work, or they are very convoluted or require you to abandon using custom fields which isn't really a workaround but more of a "throwing in the towel". One suggestion was to simply update the Elements.xml file for the EventReceiver by simply adding a "Synchronous" entry to force the event to occur synchronously instead of asynchronously. At first I thought this was too easy and too good to be true. As it turns out, I was right. :)
You can't nest a custom ListFieldIterator inside a custom control and expect your custom fields to save the data that they contain. You MUST use the ListFieldIterator directly in your form template. Period! If you try and wrap the ListFieldIterator with your custom fields in a custom control you will be very frustrated with the results.
As a side note, once the document has been uploaded and an ID has been created, you CAN enter data into your custom fields in the Edit Form and the values WILL be saved because now your code will actually be able to reference the ListItem's ID value since the ListItem will already exist in the list. Again, this is contrary to a custom upload form where the ID for the ListItem does not yet exist because you haven't actually uploaded the document yet.
I REALLY wish that Microsoft would provide some sort of update that would allow developers to get around this issue with Document Libraries and I think that it's pretty clear that they knew this was an issue when they first released SharePoint which is why the default behavior for the Document Library "New Form" is to present the user with a standalone Upload form which then redirects the user to the Edit Form so that they could avoid all of this. Of course this leaves developers who wish to allow users to upload a document and enter data on the same screen without a leg to stand on when using custom fields. Your only alternative is to use custom forms and programmatically set all of the field values and add in tons and tons of conditional logic for every single permutation of all the different fields and layout possibilities but that's a whole other animal and certainly defeats the whole reason why Microsoft created the concept of custom fields in the first place!
I have made a report in Crystal Reports, it has a detail section, i have dragged a variable carrying text and if the paragraph of the text longer, i want its half of the part should be gone to the next page, as we see in text books and as it is a standward way on A4 paper.
When i write a variable carrying data in text for detail, this problem occurs. I had used some algorithm or like that to divide the data into two parts and made two variables, but as data can be html also so that algorithm does not work in very good manner. I just want to use crystal reports functionality. Thanks in advance.I am attaching an image for further understanding.
The history field should have a property called 'keep together'. I'm guessing its set to true and should be changed to false to allow the field to be split across a page break.
i want to generate an ID card for various group members belonging to different section. Each has a different format depending on what user selects e.g
What i also want is the photo portion should be adjustable in the area where the user wants to amd also the photo that comes from database should be able to crop as per the user requirements.
Is this possible doing using Crystal Reports.Any tutorials and guidelines will be helpful as i am absolutely new to using Crystal Reports.
If not using=Crystal Reports,what is the other best option.
Please help me to get the ID card to be generated dynamically.
If you wanted to narrow it down to just one report you could something similar to what MD-Tech suggested but use sections that are hidden or shown depending on the user selection.
There are three options:
two reports - like what MD-Tech is suggesting. two reports, on average, are more difficult to maintain.
one report/two sections - like what BUkHix suggests. you create the desired formatting in two separate sections, then use a parameter to hide/show the desired section
one report/two sub-reports - this gives you the most, finely-grained control over the formatting. the sub-reports display can also be controlled by a parameter.
In any case, you can control the image's X (distance from left margin) in v 11.0 using a conditional formula. In v 12.0, you can also control the Width property with a conditional formula. A conditional formula can reference a parameter field, so the positioning can make use of a user-supplied value.
You will also need to experiment with the image types, as Crystal Reports supports a limited set (JPG and BMP for sure).
Splitting this into 2 answers so much info incoming; firstly loading separate reports:
it is possible to select which reports are loaded at runtime by conditionally calling the Load() function of the document class. An example of this would be (in c++):
ReportDocument myDocument = gcnew myDocument();
if(wideIDcard)
{
myDocument->Load("wideIDCard.rpt");
}
else
{
myDocument->Load("narrowIDCard.rpt");
}
where the boolean wideIDCard is set from a dropdown box etc. from a front end. The ReportDocument myDocument can then be sent to the report viewer to view that report.
The quickest way to do this whould be to have 2 separate reports and then have the code Load() the correct one dependent on the user selection, which would come from a separate windows form. It is possible (though difficult) to create this form in such a way as to use it to set all the parameters for the report if you need it to be a single entry form.