Hi,
I'm reading multiple InfoPath Textbox (set to display multiple lines) using OpenXML and generating a word document based on a template collecting data from InfoPath. I'm using following code, the code gives error in AddMultiLineText at Paragraph p = sdt.GetFirstChild<SdtContentBlock>().GetFirstChild<Paragraph>(); I'm quite new to Infopath and OpenXML, I would appreciate some help ASAP as its holding me in my project:
Event Receiver
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
this.EventFiringEnabled = false;
string siteUrl = properties.WebUrl;
SPListItem item = properties.ListItem;
SPWeb web = properties.Web;
SPList lib = web.Lists["DocLib"];
SPFile file = lib.RootFolder.Files["template.docx"];
string generatedDoc = "";
if (file != null)
{
byte[] templateBytes = file.OpenBinary();
using (MemoryStream ms = new MemoryStream())
{
ms.Write(templateBytes, 0, (int)templateBytes.Length);
byte[] convertedDocBytes = ConvertInfoPathToWord(ms, item.File);
generatedDoc = item["LinkFilename"].ToString().Replace("xml", "docx");
SPFile newFile =
lib.RootFolder.Files.Add(generatedDoc, convertedDocBytes, true);
ms.Close();
}
}
}
private byte[] ConvertInfoPathToWord(MemoryStream ms, SPFile file)
{
byte[] bytes = file.OpenBinary();
using (MemoryStream msInternal = new MemoryStream(bytes))
{
XmlDocument doc = new XmlDocument();
doc.Load(msInternal);
XPathNavigator root = doc.CreateNavigator();
root.MoveToFollowing(XPathNodeType.Element);
string ns = root.GetNamespace("my");
XmlNamespaceManager nsMgr = new XmlNamespaceManager(new NameTable());
nsMgr.AddNamespace("my", ns);
string multiLineText1 = root.SelectSingleNode(
"/my:myFields/my:field1", nsMgr).Value;
string multiLineText2 = root.SelectSingleNode(
"/my:myFields/my:field2", nsMgr).Value;
using (WordprocessingDocument myDoc =
WordprocessingDocument.Open(ms, true))
{
MainDocumentPart mainPart = myDoc.MainDocumentPart;
List<OpenXmlElement> sdtList = InfoPathToWord.GetContentControl(
mainPart.Document, "multilinetext1");
InfoPathToWord.AddMultiLineText(multiLineText1, ref sdtList);
List<OpenXmlElement> sdtList = InfoPathToWord.GetContentControl(
mainPart.Document, "multilinetext2");
InfoPathToWord.AddMultiLineText(multiLineText2, ref sdtList);
myDoc.Close();
}
msInternal.Close();
}
return ms.ToArray();
}
public static List<OpenXmlElement> GetContentControl(
Document doc, string name)
{
List<OpenXmlElement> list = new List<OpenXmlElement>();
List<SdtBlock> sdtList = doc.Descendants<SdtBlock>()
.Where(s => name.Contains(s.SdtProperties.GetFirstChild<SdtAlias>()
.Val.Value)).ToList();
if (sdtList.Count == 0)
{
List<SdtRun> sdtRunList = doc.Descendants<SdtRun>()
.Where(s => name.Contains(s.SdtProperties.GetFirstChild<SdtAlias>()
.Val.Value)).ToList();
foreach (SdtRun sdt in sdtRunList)
{
list.Add(sdt);
}
}
else
{
foreach (SdtBlock sdt in sdtList)
{
list.Add(sdt);
}
}
return list;
}
public static void AddMultiLineText(
string multiLineText, ref List<OpenXmlElement> sdtList)
{
string[] lines = multiLineText.Split(new char[] { '\n' });
if (sdtList.Count != 0)
{
foreach (OpenXmlElement sdt in sdtList)
{
for (int i = 0; i < lines.Length; i++)
{
Paragraph p =
sdt.GetFirstChild<SdtContentBlock>().GetFirstChild<Paragraph>(); //this ERRORS
if (i == 0)
{
InfoPathToWord.WriteText(lines[i], ref p);
}
else
{
Paragraph pNext = sdt.AppendChild((Paragraph)p.Clone());
InfoPathToWord.WriteText(lines[i], ref pNext);
}
}
}
}
}