Question

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;
Was it helpful?

Solution

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;
    }

OTHER TIPS

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\"; } } ";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top