0

I am developing a web-part that will generate word-documents. The word-documents are generated on the basis of a template document which has defined content controls. I want to retrieve data from SharePoint and put the data inside these content controls. Everything was working good for me when I had only one content control in my template, but after expanding the template document with more content controls I get exceptions. It seems like I am not finding the content controls. This is my method:

private void CreateReport(SPFile file)

        {
            var byteArray = file.OpenBinary();
            using (var mem = new MemoryStream())
            {
                mem.Write(byteArray, 0, byteArray.Length);
                try
                {
                    using (var wordDoc = WordprocessingDocument.Open(mem, true))
                    {
                        var mainPart = wordDoc.MainDocumentPart;

                        var firstName = mainPart.Document.Body.Descendants<SdtBlock>().Where
                            (r => r.SdtProperties.GetFirstChild<Tag>().Val == "FirstName").Single();
                        var t = firstName.Descendants<Text>().Single();
                        t.Text = _firstName;

                         var lastName = mainPart.Document.Body.Descendants<SdtBlock>().Where
                            (r => r.SdtProperties.GetFirstChild<Tag>().Val == "LastName").Single();
                         var t2= lastName.Descendants<Text>().Single();
                         t2.Text = _lastName;

                        mainPart.Document.Save();
                        SaveFileToSp(mem);
                    }

                }
                catch (FileFormatException)
                {
                }
            }
        }

This is the exception I get:

An exception of type 'System.InvalidOperationException' occurred in System.Core.dll but was not handled in user code. Innerexception: Null

Any tips for me on how I can write better method for finding controls?

2
  • Do you have to use code to achieve this? Have you tried using the word template mapped to library or content type and add quick parts mapped for your Sharepoint columns so that the word document is populated for you.
    – Simon Doy
    Commented Mar 12, 2015 at 7:32
  • I have to use code because I retrieve data from User profiles services and a couple of other content types, and merge it in to one document.
    – Ilyas
    Commented Mar 12, 2015 at 9:42

2 Answers 2

0

Simplify your code and remove all the nested Linq statements at least then you can debug and see where it is going wrong.

1
  • I know where it goes wrong, but not really found any good solutions. Here: var t2= lastName.Descendants<Text>().Single();
    – Ilyas
    Commented Mar 13, 2015 at 19:14
0

Found another way to loop, and fix my problem:

private static void ReplaceTags(MainDocumentPart mainPart, string tagName, string tagValue) { //grab all the tag fields IEnumerable tagFields = mainPart.Document.Body.Descendants().Where (r => r.SdtProperties.GetFirstChild().Val == tagName);

foreach (var field in tagFields)
{
    //remove all paragraphs from the content block
    field.SdtContentBlock.RemoveAllChildren<Paragraph>();
    //create a new paragraph containing a run and a text element
    Paragraph newParagraph = new Paragraph();
    Run newRun = new Run();
    Text newText = new Text(tagValue);
    newRun.Append(newText);
    newParagraph.Append(newRun);
    //add the new paragraph to the content block
    field.SdtContentBlock.Append(newParagraph);
}

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.