I have finally, successfully, figured out how to fill a PDF with an XFA Form with my custom data using iTextSharp.
The problem is that I've lost the code that I had that let me make the XFA read-only. I have made the horrible mistake of changing my code before committing a working version to my source control. And now, after searching Google for like an hour I still can't find it :( If someone could remind me of the code that would be much appreciated.
PdfReader.unethicalreading = true;
PdfReader reader = new PdfReader(pdfFileName);
PdfStamper stamper = new PdfStamper(reader, ms);
XfaForm xfa = new XfaForm(reader);
XmlDocument doc = new XmlDocument();
doc.LoadXml(CreateXmaData(XDocument.Parse(xfa.DomDocument.InnerXml)));
xfa.DomDocument = doc;
xfa.Changed = true;
XfaForm.SetXfa(xfa, stamper.Reader, stamper.Writer);
PdfAction action = new PdfAction(PdfAction.PRINTDIALOG);
stamper.Writer.SetOpenAction(action);
// Somewhere here I had the code that made my XFA form read only...
stamper.Writer.CloseStream = false;
stamper.Close();
reader.Close();
byte[] buffer = new byte[ms.Position];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
return buffer;
Not sure if I was dreaming that I had the read-only working or what, and I doubt that this is the best way, but here is how I was finally able to do it:
...
doc.LoadXml(CreateXmaData(XDocument.Parse(xfa.DomDocument.InnerXml)));
PdfAction readOnlyAction = PdfAction
.JavaScript(MakeReadOnly(xfa.DomDocument.InnerXml), stamper.Writer);
stamper.Writer.AddJavaScript(readOnlyAction);
xfa.DomDocument = doc;
...
private string MakeReadOnly(string xml)
{
string formName = string.Empty;
int subFormStart = xml.IndexOf("<subform", 0);
if (subFormStart > -1)
{
int nameTagStart = xml.IndexOf("name", subFormStart);
int nameStart = xml.IndexOf("\"", nameTagStart);
int nameEnd = xml.IndexOf("\"", nameStart + 1);
formName = xml.Substring(nameStart + 1, (nameEnd - nameStart) - 1);
}
string readOnlyFunction = "ProcessAllFields(xfa.form." + formName + ");";
readOnlyFunction += "function ProcessAllFields(oNode) {";
readOnlyFunction += " if (oNode.className == \"exclGroup\" || oNode.className == \"subform\" || oNode.className == \"subformSet\" || oNode.className == \"area\") { ";
readOnlyFunction += " for (var i = 0; i < oNode.nodes.length; i++) {";
readOnlyFunction += " var oChildNode = oNode.nodes.item(i); ProcessAllFields(oChildNode);";
readOnlyFunction += " }";
readOnlyFunction += " } else if (oNode.className == \"field\") {";
readOnlyFunction += " oNode.access = \"readOnly\"";
readOnlyFunction += " }";
readOnlyFunction += "}";
return readOnlyFunction;
}
This worked for me
String script = "for (var nPageCount = 0; nPageCount < xfa.host.numPages; nPageCount++) { var oFields = xfa.layout.pageContent(nPageCount, \"subform\"); var nNodesLength = oFields.length;";
script += "for (var nNodeCount = 0; nNodeCount < nNodesLength; nNodeCount++) { oFields.item(nNodeCount).access = \"readOnly\"; } } ";
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.