none
How to delete data or table within two bookmarks from word document using OpenXml in C# RRS feed

  • Question

  • I am creating word document in C# using OpenXML. I can insert my Text after specified bookmark, but how can delete data within two bookmarks.

    Following is the code to insert text after specified Bookmark.

     string fileName = @"C:\Users\sharepointadmin\Desktop\volc.docx";

                TableValues ObjTableValues = new TableValues();
                List<TableValues> allValues = new System.Collections.Generic.List<TableValues>();

                for (int i = 1; i <= 5; i++)
                {
                    ObjTableValues = new TableValues();
                    ObjTableValues.EmpID = i.ToString();
                    ObjTableValues.EmpName = "Emp" + i.ToString();
                    ObjTableValues.EmpDesig = "SE";
                    ObjTableValues.EmpDept = "Software";

                    allValues.Add(ObjTableValues);
                    //ConvertMailMergeEscape(fileName);

                }

                AddTable(fileName, allValues);

            }
                using (var document = WordprocessingDocument.Open(fileName, true))
                {
                    IDictionary<String, BookmarkStart> bookmarkMap = new Dictionary<String, BookmarkStart>();               

                    var doc = document.MainDocumentPart.Document;
                    var mainpart = document.MainDocumentPart;
                    var res = from ObjTableValues in mainpart.Document.Body.Descendants<BookmarkStart>() where ObjTableValues.Name == "testbookmark" select ObjTableValues;                
                    var bookmark = res.SingleOrDefault();
                    if (bookmark != null)
                    {
                        var parent = bookmark.Parent;
     run.Append(text);
                        Paragraph newParagraph = new Paragraph(run);

                        // insert after bookmark parent
                        parent.InsertAfterSelf(newParagraph);
      foreach (BookmarkStart bookmarkStart in document.MainDocumentPart.RootElement.Descendants<BookmarkStart>())
                    {
                        bookmarkMap[bookmarkStart.Name] = bookmarkStart;
                    }

                    MoveToRangeStart ranstart = new MoveToRangeStart();


                    foreach (BookmarkStart bookmarkStart in bookmarkMap.Values)
                    {
                        Run bookmarkText = bookmarkStart.NextSibling<Run>();
                        if (bookmarkText != null)
                        {
                            //bookmarkText.GetFirstChild<Text>().Text = "blah";
                        }
                    }

                    DocumentFormat.OpenXml.Wordprocessing.Table table = new DocumentFormat.OpenXml.Wordprocessing.Table();

                    TableProperties props = new TableProperties(
                        new TableBorders(
                        new TopBorder
                        {
                            Val = new EnumValue<BorderValues>(BorderValues.Single),
                            Size = 12
                        },
                        new BottomBorder
                        {
                            Val = new EnumValue<BorderValues>(BorderValues.Single),
                            Size = 12
                        },
                        new LeftBorder
                        {
                            Val = new EnumValue<BorderValues>(BorderValues.Single),
                            Size = 12
                        },
                        new RightBorder
                        {
                            Val = new EnumValue<BorderValues>(BorderValues.Single),
                            Size = 12
                        },
                        new InsideHorizontalBorder
                        {
                            Val = new EnumValue<BorderValues>(BorderValues.Single),
                            Size = 12
                        },
                        new InsideVerticalBorder
                        {
                            Val = new EnumValue<BorderValues>(BorderValues.Single),
                            Size = 12
                        }));

                    table.AppendChild<TableProperties>(props);

                    foreach (TableValues Tableitem in allValues)
                    {
                        var tr = new DocumentFormat.OpenXml.Wordprocessing.TableRow();

                        var tc = new DocumentFormat.OpenXml.Wordprocessing.TableCell();

                        tc.Append(new Paragraph(new Run(new Text(Tableitem.EmpID))));
                        tr.Append(tc);

                        tc = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
                        tc.Append(new Paragraph(new Run(new Text(Tableitem.EmpName))));
                        tr.Append(tc);

                        tc = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
                        tc.Append(new Paragraph(new Run(new Text(Tableitem.EmpDesig))));
                        tr.Append(tc);

                        tc = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
                        tc.Append(new Paragraph(new Run(new Text(Tableitem.EmpDept))));
                        tr.Append(tc);

                        table.Append(tr);

                    }
                    doc.Body.Append(table);
                    doc.Save();
                }
            }
        }
    }

    Can any one help me please.

    Tuesday, October 30, 2012 11:56 AM

Answers

  • Hi SAM,

    Thanks for posting in the MSDN Forum.

     How to delete data or table within two bookmarks from word document

    This is a complex problem, as far as I know that book mark can mutual nested. I means that there might exist following situation: On bookmark start inside of on specific bookmark and finished at the part which you want to remove. So it will be very difficult to deceid which Element need to remove. However the principle of this issue is iterate every element and to see whether it need to remove, then collection them together and remove them after iterated. I suppose that there will not exists the bookmark which begin inside the start bookmark(Mark1) and finished at the part which will remove. And the parts after bookmark(Mark2) will not be removed.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using DocumentFormat.OpenXml;
    using DocumentFormat.OpenXml.Wordprocessing;
    using DocumentFormat.OpenXml.Packaging;
    using com.mksword.Net.OpenXmlTools;
    using System.Xml;
    
    namespace ConsoleApplication5
    {
        public class DeleteBetweenTowMark : WordprocessingDocumentUtil 
        {
            public void Action()
            {
                HandlerDocumentLocal(DeleteBetweenMarks, true);
            }
    
            private bool DeleteBetweenMarks(WordprocessingDocument WPD)
            {
                string startMark = "Mark2";
                string endMark = "Mark3";
                bool del = false;
                bool result = false;
                MainDocumentPart MDP = WPD.MainDocumentPart;
                Document D = MDP.Document;
                Body B = D.Body;
                string startId = string.Empty;
                bool ready = false;
                List<OpenXmlElement> w = new List<OpenXmlElement>();
                foreach (OpenXmlElement element in B.ChildElements)
                {
                    SetLog(element.OuterXml, OXULogType.WARN);
                    if (!del && !ready)
                    {
                        if (element is Paragraph)
                        {
                            foreach (OpenXmlElement PE in element.ChildElements)
                            {
                                if (PE is BookmarkStart)
                                {
                                    BookmarkStart BS = (BookmarkStart)PE;
                                    string Name = BS.Name;
                                    if (Name.Equals(startMark))
                                    {
                                        ready = true;
                                        startId = BS.Id;
                                    }
                                }
                                else if (PE is BookmarkEnd)
                                {
                                    BookmarkEnd BE = (BookmarkEnd)PE;
                                    string Id = BE.Id;
                                    if (Id.Equals(startId))
                                    {
                                        del = true;
                                    }
                                }
                                else if (del && ready)
                                {
                                    PE.Remove();
                                }
                            }
                        }
                    }
                    else if (!del && ready)
                    {
                        SetLog(element.OuterXml, OXULogType.WARN);
                        if (element is Paragraph && !del)
                        {
                            foreach (OpenXmlElement PE in element.ChildElements)
                            {
                                if (PE is BookmarkEnd)
                                {
                                    BookmarkEnd BE = (BookmarkEnd)PE;
                                    string Id = BE.Id;
                                    if (Id.Equals(startId))
                                    {
                                        del = true;
                                    }
                                }
                                else if (del) 
                                {
                                    SetLog(PE.OuterXml, OXULogType.INFO);
                                    PE.Remove();
                                }
                            }
                        }
                    }
                    else if (del && ready)
                    {
                        if (element is Paragraph &&
                            element.Descendants<BookmarkStart>()
                            .Where(BX => BX.Name == endMark).Count() == 1)
                        {
                            foreach (OpenXmlElement PE in element.ChildElements)
                            {
                                if (PE is BookmarkStart)
                                {
                                    BookmarkStart BS = (BookmarkStart)PE;
                                    string Name = BS.Name;
                                    if (Name.Equals(endMark))
                                    {
                                        del = false;
                                        ready = false;
                                    }
                                }
                                else if (del && ready)
                                {
                                    PE.Remove();
                                }
                            }
                        }
                        else
                        {
                            w.Add(element);
                        }
                    }
                }
                foreach (OpenXmlElement e in w)
                {
                    SetLog(e.OuterXml, OXULogType.FATAL);
                    e.Remove();
                }
                D.Save();
                result = true;
                return result;
            }
        }
    }

    I hope it can help you.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, October 31, 2012 6:00 AM
    Moderator