4

I'm really having trouble in editing bookmarks in a Word template using Document.Format.OpenXML and then saving it to a new PDF file. I cannot use Microsoft.Word.Interop as it gives a COM error on the server.

My code is this:

public static void CreateWordDoc(string templatePath, string destinationPath, Dictionary<string, dynamic> dictionary)
{

    byte[] byteArray = File.ReadAllBytes(templatePath);
    using (MemoryStream stream = new MemoryStream())
    {
        stream.Write(byteArray, 0, (int)byteArray.Length);
        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
        {
            var bookmarks = (from bm in wordDoc.MainDocumentPart.Document.Body.Descendants<BookmarkStart>()
                             select bm).ToList();

            foreach (BookmarkStart mark in bookmarks)
            {

                if (mark.Name != "Table" && mark.Name != "_GoBack")
                {

                 UpdateBookmark(dictionary, mark);//Not doing anything

                }
                else if (mark.Name != "Table")
                {
                    //  CreateTable(dictionary, wordDoc, mark);
                }
            }
           File.WriteAllBytes("D:\\RohitDocs\\newfile_rohitsingh.docx", stream.ToArray());

            wordDoc.Close();

        }
        // Save the file with the new name

    }
}

private static void UpdateBookmark(Dictionary<string, dynamic> dictionary, BookmarkStart mark)
{
    string name = mark.Name;
    string value = dictionary[name];

    Run run = new Run(new Text(value));
    RunProperties props = new RunProperties();

    props.AppendChild(new FontSize() { Val = "20" });
    run.RunProperties = props;
    var paragraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph(run);
    mark.Parent.InsertAfterSelf(paragraph);

    paragraph.PreviousSibling().Remove();
    mark.Remove();
}

I was trying to replace bookmarks with my text but the UpdateBookmark method doesn't work. I'm writing stream and saving it because I thought if bookmarks are replaced then I can save it to another file.

halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

0

I think you want to make sure that when you reference mark.Parent that you are getting the correct instance that you are expecting.

Once you get a reference to the correct Paragraph element where your content should go, use the following code to add/swap the run.

// assuming you have a reference to a paragraph called "p"
p.AppendChild<Run>(new Run(new Text(content)) { RunProperties = props });

// and here is some code to remove a run
p.RemoveChild<Run>(run);

To answers the second part of your question, when I did a similar project a few years ago we used iTextSharp to create PDFs from Docx. It worked very well and the API was easy to grok. We even added password encryption and embedded watermarks to the PDFs.

Glenn Ferrie
  • 10,290
  • 3
  • 42
  • 73