Monday, April 19, 2010

Programmatically create a new form in the Form Library in SharePoint

As you will learn that, creating a new form from a from library in SharePoint is not that easy as compared to Document Library. Because in a Form Library the template stored in XSN formate and you need to first extract the xml out of it.

In the first section, we will create the instance of Form Library of a SharePoint site.

SPDocumentLibrary list = null;
using (SPSite objSite = new SPSite("http://soumyendra:555/Forms"))
{
using (SPWeb objWeb = objSite.OpenWeb())
{
list = objWeb.Lists["Person Address"] as SPDocumentLibrary;
}
}

here "Person Address" is the name of the form library.

Next we will pick the template file attached to the form library. We can get that by using SPList.DocumentTemplateUrl property.

Then we need to extract the template file (XSN) using some extract utility. Here I am using CabinetExtractAndCompress. You can download the utility from Code Project and use it.

Then, by using the utility we first create a physical directory and extract the XSN file. After that, by using File Stream object, we read the file content and get the byte array.

byte[] data = null;
SPFile file = list.ParentWeb.GetFile(list.DocumentTemplateUrl);
Extract cab = new Extract();
string szFolder = string.Concat(System.IO.Path.GetTempPath(), list.Title, "\\");

if (!Directory.Exists(szFolder))
Directory.CreateDirectory(szFolder);

cab.ExtractStream(file.OpenBinaryStream(), szFolder);
FileStream fs = new FileStream(szFolder + "template.xml", FileMode.Open);
try
{
data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
}
finally
{
fs.Close();
}


Next, we will have the MomoryStream to convert the byte array to a XML document. This xml document can be used for updating the values of the fields in the document.

MemoryStream inStream = new MemoryStream(data);
XmlTextReader reader = new XmlTextReader(inStream);
XmlDocument xd = new XmlDocument();
xd.Load(reader);
reader.Close();
inStream.Close();

string strLibraryUrl = "http://soumyendra:555/Forms/" + list.DocumentTemplateUrl;


This is a very important step. Since we are using a different file as a source compared to the file uploaded in the form library, we need to update the reference as well.

for (int index = 0; index <>
{
if (xd.ChildNodes[index].Name == "mso-infoPathSolution")
{
string sHref = string.Format("href=\"{0}\"", strLibraryUrl);
Regex regEx = new Regex("href=\".*\"");

if (regEx.IsMatch(xd.ChildNodes[index].Value))
{
xd.ChildNodes[index].Value = regEx.Replace(xd.ChildNodes[index].Value, sHref);
}
else
{
xd.ChildNodes[index].Value = string.Concat(xd.ChildNodes[index].Value, sHref, ' ');
}
}
}

The following steps are for updating the fields in the InfoPath form. We need to loop through the child elements of the form and update the values of the form as required.

//gets the root element from the xml document XmlElement
root = xd.DocumentElement;
for (int index = 0; index <>
{
if (root.ChildNodes[index].Name == "my:Name")
{
root.ChildNodes[index].InnerText = "Somu";
}
else if (root.ChildNodes[index].Name == "my:Address")
{
root.ChildNodes[index].InnerText = "Delhi";
}
else if (root.ChildNodes[index].Name == "my:Phone")
{
root.ChildNodes[index].InnerText = "123456";
}
else if (root.ChildNodes[index].Name == "my:Email")
{
root.ChildNodes[index].InnerText = "somu@gamil.com";
}
}

The final step is to save the file back in the form library. For this we create the instance of the list and Add the file as follows.

using (SPSite objSite = new SPSite("http://soumyendra:555/Forms"))
{
using (SPWeb objWeb = objSite.OpenWeb())
{
// saves the XML Document back as a file
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
SPFile newFile = objWeb.Folders["Person Address"].Files.Add("Somu.xml", (encoding.GetBytes(xd.OuterXml)), true);
}
}


The above post created with the help of Daniel Halan. Please let me know if you have ant doubts on the above mention steps.

Thanks,
Soumyendra

21 comments:

Soumyendra Sharma said...

If anyone required the entire source, please leave a comment here.

TC,
Soumyendra

Dipti said...

This is exactly what I need ...I desperately want source code of implementation mentioned in this blog , would you please send me on "diptichhatrapati@gmail.com" ? It will be highly appreciated.

Thanks And Regards,
Dipti Chhatrapati

Stephen said...

Can you send me the Source Code at stephen_vicky@yahoo.com

Unknown said...

Soumyendra,


This is what I was looking for. Can you please send me the source code to ch.sudhirbabu@gmail.com

I appreciate it.
Thanks.
Sudhir

Anonymous said...

Soumyendra,

This is what i need.. Can you please send me the source code on hema.tahadil@umail.uom.ac.mu?

Unknown said...

Please send me the complete code at ahmed.monsur@gmail.com

Unknown said...

please send me on "priyarane30@gmail.com" ? It will be highly appreciated.

LesZ said...

I too would appreciate the source.

Thanks,

les.zatony@gmail.com

Pritesh said...

exactly I needed the source code. pdhmelia@gmail.com

Ash said...

I have deployed browser enabled infopath form and added in the form library as content type,
kindly send me the source.
ashfaq02@live.com

Pritesh said...

Thank you Ashfaq for the reply. I was able to create InfoPath form programmatically. I utilized deployed InfoPath template.

Unknown said...

Do you still have the code? Kindly share. Kkdvelasco@gmail.com

Unknown said...

Do you still have the code? Kindly share. Kkdvelasco@gmail.com

Unknown said...
This comment has been removed by the author.
Unknown said...

Please share at hfayyaz.rasool@gmail.com

Unknown said...

please give complete code on ubaidquraishee@gmail.com. Thanks

Unknown said...

please share code at bnetter@ucla.edu

Thanks!

Unknown said...

please share code at bnetter@ucla.edu

Thanks!

Ybenk's Blog said...

Please share the code to indarto77@live.com

Thx so much

איציק said...

Please share the code to itzikf6@gmail.com

Unknown said...

Please share the code at emmanuel.macron@elysee.fr