0

I have a word template that I need to change insering some text at some precise spots.

I already done an header but I used only the InnerXML and I can try to not use this function it could be better.

My code:

using (WordprocessingDocument myDoc = WordprocessingDocument.Open(destinationFile, true))
{
    var mainDocumentPart = myDoc.MainDocumentPart;

    //Body
    var body = mainDocumentPart.Document.Body;
    List<SdtElement> SdtBlocks = myDoc.MainDocumentPart.Document.Descendants<SdtElement>().ToList();

    //var text = SdtBlocks[0].Descendants<Text>().First().Text;
    //SdtBlocks[0].Descendants<Text>().First().Text.Replace(SdtBlocks[0].InnerText, cv.Resume);

    foreach (var element in SdtBlocks)
    {
        if (element.InnerText.Contains("Resume"))
        {
            element.Descendants<Text>().First().Text = cv.Resume;
            System.Diagnostics.Debug.WriteLine(element.Descendants<Text>().First().Text);
        }
        //foreach(var text in element.Descendants<Text>())
        //{
        //}
    }

cv is my objet with my data.

So actually, doing this doesn't change the part containing "Resume" on my final word. Also, I will have some list to add on this word and I don't know how to. I tried to find some info on the internet and on openXML related site (including the one of Eric White) but I couldn't find the solution.

Any idea and to fix this and also for the second part ?

EDIT : So I finally fixed the 1st part thanks to @petedelis :

var text = SdtBlocks[0].Descendants<Text>().First().Text;
Paragraph newParagraph = new Paragraph();
Run newRun = new Run();
Text newText = new Text(cv.Resume);
newRun.Append(newText);
newParagraph.Append(newRun);
SdtBlocks[0].Parent.InsertBefore(newParagraph, SdtBlocks[0]);
SdtBlocks[0].Remove();

Now I am on the table part : My table looks like this : Image of the template

I need to duplicate the second row for each mission. Actually I have this :

foreach (Mission mission in listeMission)
                {
                    SdtRow newRow = new SdtRow();
                    SdtContentRow newContent = new SdtContentRow();
                    newParagraph = new Paragraph();
                    newRun = new Run();
                    Text cell = new Text(mission.Titre);
                    newRun.Append(cell);
                    newParagraph.Append(newRun);
                    newContent.Append(newParagraph);
                    newRow.Append(newContent);
                    rowTemplate.RemoveAllChildren();
                    rowTemplate.Append(newContent);
                    rowTemplate.Parent.InsertBeforeSelf(newRow);
}

But the result is not what I want. Any ideas ?

Nicolas S.
  • 173
  • 2
  • 12
  • 1
    I'm not 100% clear what your issue is here but does [my answer here](https://stackoverflow.com/a/29099130/3791802) help at all? – petelids Jun 22 '17 at 16:32
  • For the Resume it did help ! Thank you ! :D Now I need to understand the table part, Gonna edit the question – Nicolas S. Jun 23 '17 at 08:09
  • Edited, do you have an idea ? @petelids – Nicolas S. Jun 23 '17 at 08:19
  • What do you mean by "*this is not running*" ? do you get any error message or... ? Could you show what you get vs what you want ? – Rafalon Jun 23 '17 at 08:26
  • Nono but this is not what I want (I did not express myself correctly, gonna edit). But I want rows like the template one – Nicolas S. Jun 23 '17 at 08:30
  • Edited @Rafalon – Nicolas S. Jun 23 '17 at 08:31
  • And so what are the differences between the result and what you want ? Can you show us the result ? – Rafalon Jun 23 '17 at 08:32
  • Here you are : [link](https://puu.sh/ws76c/7717f5b4df.png) As you can see, the new phrase added is under the table and I want to have something like this : [link](https://puu.sh/ws7aT/a3c73a942d.png) @Rafalon – Nicolas S. Jun 23 '17 at 08:40
  • When/where is your `rowTemplate` initialized ? – Rafalon Jun 23 '17 at 09:02
  • Before, `// Find the first table in the document. Table table = myDoc.MainDocumentPart.Document.Body.Elements().Skip(1).First(); // Find the second row in the table. SdtRow rowTemplate = table.Elements().First();` @Rafalon
    – Nicolas S. Jun 23 '17 at 09:03
  • `rowTemplate.Parent.InsertBeforeSelf(newRow);` doesn't quite look right to me - you don't want to insert it before the table, you want to insert it at the end of the table. I'd try changing that line to `rowTemplate.Parent.Append(newRow);` – petelids Jun 23 '17 at 12:26

1 Answers1

0

You say you are finding the first table in the document, and then the second row of this table with this code :

// Find the first table in the document. 
Table table = myDoc.MainDocumentPart.Document.Body.Elements<Table>().Skip(‌​1).First(); 
// Find the second row in the table. 
SdtRow rowTemplate = table.Elements<SdtRow>().First();

I think you are in fact finding the second table in the document, and then the first row of this table with it.

Maybe try the following instead ?

// Find the first table in the document. 
Table table = myDoc.MainDocumentPart.Document.Body.Elements<Table>().First(); 
// Find the second row in the table. 
SdtRow rowTemplate = table.Elements<SdtRow>().Skip(1).First();
Rafalon
  • 4,450
  • 2
  • 16
  • 30
  • On my document, this is my 1st table : https://puu.sh/ws89i/a359e3b37a.png There is also a "table" before but for it is not a real one. There error is "Sequence contains no elements", as expected – Nicolas S. Jun 23 '17 at 09:15