Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Thu Dec 18, 2025 11:02 am

Hello support team!

This time I want to ask whether you can provide me with some sample code regarding the following requirement.
Suppose you have a bookmark that covers a region in a document. This region can be some columns, rows or multiple cells in a table. It can also be cover multiple paragraphs or some other fancy part of the document. All the content covered by the bookmark should be deleted.

Within Microsoft Word I do the following the achieve this:
1. Use Control+G to navigate to the requested bookmark. This will select all the content covered by it.
2. Press "Delete" to delete all the content selected by the previous step.

Here is the marco that Microsoft Word records ("S3" is the name of the bookmark in my example):
Code: Select all
Sub Makro1()
    Selection.GoTo What:=wdGoToBookmark, Name:="S3"
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = ""
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Cut
End Sub


How can this be achieved using the Spire.Doc for Java-API, please?

I've already tried the following:
Code: Select all
BookmarksNavigator navigator = new BookmarksNavigator(document);
navigator.moveToBookmark("S3");
navigator.deleteBookmarkContent(false);


But this does not work, if the bookmark covers a table row or a table column.

If it covers a table row, I receive the following exception:
Code: Select all
java.lang.UnsupportedOperationException: Not supported deleting content between bookmarks in different paragraphs
   at com.spire.doc.documents.BookmarksNavigator.spr═┩—(Unknown Source)
   at com.spire.doc.documents.BookmarksNavigator.deleteBookmarkContent(Unknown Source)


If it covers a table column, I receive the following exception:
Code: Select all
com.spire.doc.packages.sprztx: Specified argument was out of the range of valid values.
Parameter name: Parameter name: index
com.spire.doc.packages.spryor.spr†©(List.java:489)
com.spire.doc.packages.sprgpga.spr▢§(Unknown Source)
com.spire.doc.collections.DocumentObjectCollection.get_Item(Unknown Source)
com.spire.doc.collections.DocumentObjectCollection.get(Unknown Source)
com.spire.doc.collections.BodyRegionCollection.spr▆(Unknown Source)
com.spire.doc.collections.BodyRegionCollection.get(Unknown Source)
com.spire.doc.documents.BookmarksNavigator.spr▤┩—(Unknown Source)
com.spire.doc.documents.BookmarksNavigator.spr═┩—(Unknown Source)
com.spire.doc.documents.BookmarksNavigator.deleteBookmarkContent(Unknown Source)


Kind regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Fri Dec 19, 2025 2:52 am

Dear Marcus,

Thank you for your inquiry.
A bookmark consists of a start marker, content, and an end marker. In Spire.Doc, when you perform operations on a bookmark, the content between its start and end markers is retrieved and placed into a separate scope object. This only works correctly if the start and end markers enclose a complete document object.
For example, if a bookmark encloses an entire table, the operation will work as expected. However, in scenarios like yours—if the bookmark's start marker is in one cell and the end marker is in another, such cells cannot exist independently of the table itself—they cannot function as standalone sub‑objects within the document scope. Consequently, operations on bookmarks spanning multiple cells may cause issues.
To achieve your goal of deleting content in specific table cells using bookmarks, we recommend placing a separate bookmark inside each target cell. Since each cell can be treated as an independent scope, this ensures that both the start and end markers of the bookmark reside within the same cell. You can then locate the cell by its bookmark name and delete its content accordingly.
I hope this helps, and I look forward to your feedback.
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Tue Dec 23, 2025 1:28 pm

Thank you for your explanation.
However, I wonder why deleting the content is possible in Microsoft Word? Obviously Microsoft Word contains logic that allows any content enclosed by a bookmark to be deleted, as I had proven by providing you the marco code. My hope was that this is possible by means of the Spire.Doc-API, too.

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Wed Dec 24, 2025 7:19 am

Dear Marcus,

Thank you for your feedback.
Please note that Spire.Doc and Microsoft Word are fundamentally different products. Microsoft Word is a client-based end-user application, while Spire.Doc is a developer-oriented middleware designed to provide programmatic access via APIs. Additionally, Microsoft Word's internal implementation is proprietary and not publicly documented, so differences in behavior are to be expected. In the future, we will continue to refine our product, using Microsoft Word's functionality as a benchmark for ongoing enhancement. After further investigation, I would like to propose an alternative approach that may better suit your requirements: first, locate the bookmark within the table structure; then, clear all content from the corresponding table cells. Please refer to the following code:
Code: Select all
  String input = "test.docx";
        String output = "RemoveBookMarkContent_java.docx";
        Document document = new Document();
        document.loadFromFile(input);
        Bookmark bookmark = document.getBookmarks().get("test");

        // Create a bookmark navigator to locate the bookmark
        BookmarksNavigator navigator = new BookmarksNavigator(document);
        navigator.moveToBookmark("test");

        // Check if the bookmark exists
        if (navigator.getCurrentBookmark() != null) {
            // Get the paragraph containing the bookmark start position
            Paragraph startOwnerParagraph = navigator.getCurrentBookmark().getBookmarkStart().getOwnerParagraph();
            TableCell cell1 = (TableCell) startOwnerParagraph.getOwner();
            int rowwStart = cell1.getOwnerRow().getRowIndex();

            // Get the paragraph containing the bookmark end position
            Paragraph endOwnerParagraph = navigator.getCurrentBookmark().getBookmarkEnd().getOwnerParagraph();
            TableCell cell2 = (TableCell) endOwnerParagraph.getOwner();
            int rowwEnd = cell2.getOwnerRow().getRowIndex();

            // Get the column range of the bookmark (first and last column)
            int firstColumn = document.getBookmarks().get("test").getFirstColumn();
            int lastColumn = document.getBookmarks().get("test").getLastColumn();

            // Print the bookmark location information
            System.out.println("Start row: Row " + rowwStart);
            System.out.println("End row: Row " + rowwEnd);
            System.out.println("Start Columns: Column " + firstColumn + ", End Columns: Column  " + lastColumn);

            Table table = (Table) document.getSections().get(0).getTables().get(0);

            // Iterate through the bookmark range (rows and columns)
            for (int row = rowwStart; row <= rowwEnd ; row++) {
                for (int col = firstColumn; col <= lastColumn ; col++) {
                    if (row < table.getRows().getCount() && col < table.getRows().get(row).getCells().getCount()) {
                        TableCell cell = table.getRows().get(row).getCells().get(col);

                        // Iterate through all paragraphs in the cell (from last to first)
                        for (int i = cell.getParagraphs().getCount() - 1; i >= 0; i--) {
                            Paragraph para = cell.getParagraphs().get(i);

                            // Delete all text in the paragraph
                            for (int j = para.getChildObjects().getCount() - 1; j >= 0; j--) {
                                DocumentObject obj = para.getChildObjects().get(j);
                                if (obj instanceof TextRange) {
                                    ((TextRange) obj).setText("");
                                }
                            }
                        }
                    }
                }
            }
        }

        document.saveToFile(output, FileFormat.Docx);


Please don't hesitate to let us know if you have any questions or need further assistance. Looking forward to your feedback.
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Mon Jan 26, 2026 11:33 am

Thank you for your effort to help me and I apologize for my late response.

The requirement is to delete table columns that are covered by bookmarks. I've attached a sample document to make it clear what I mean.
You can see from the sample document that each table column is covered by a bookmark (C1, C2 and C3).

I used the following test code to delete the 2nd column of the table:
Code: Select all
Document document = new Document("Test.docx");
Table table = document.getSections().get(0).getTables().get(0);
table.getFirstRow().getCells().removeAt(1);
document.saveToFile("Test.generated.docx", FileFormat.Docx);
 


My expectation is that the bookmark C2 is deleted, too. And this worked as expected.
However, the bookmark C1 is also deleted. I consider this as an error and request for a bugfix.

Thank you!

Kind regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Tue Jan 27, 2026 3:57 am

Dear Marcus,

Thank you for your inquiry.
To delete cells containing bookmarks, please use the following code:
Code: Select all
table.getFirstRow().getChildObjects().remove(table.getFirstRow().getCells().get(1));

Please note that table.getFirstRow().getCells().removeAt(1); is only suitable for deleting table cells that do not contain bookmarks. We look forward to your test feedback.
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Tue Jan 27, 2026 8:27 am

Thank you for your answer.
I can confirm that this will delete the 2nd cell without affecting any bookmarks.
However, the bookmarks are shifted somehow. Bookmark C2 now covers the cell containing text "C3" and bookmark C3 covers something that does not exist (a range right to the table).
Furthermore, if I delete the first cell with this code, all bookmarks are deleted, too.
So this seems to be not an ideal solution for my requirement.

The perfect solution would be if only the cell covered by the bookmark is deleted including the covering bookmark. Is this somehow possible?

Kind regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Tue Jan 27, 2026 10:04 am

Hello,

Thank you for your feedback.
When I perform the task of deleting only the cell containing bookmark "C2" in Microsoft Word, its behavior is consistent with executing the code table.getFirstRow().getChildObjects().remove(table.getFirstRow().getCells().get(1)); (Bookmark C2 covers the original "C3" cell, and bookmark "C3" appears in a blank area).
Additionally, to achieve your desired requirement (deleting the bookmark along with the cell, while ensuring bookmark "C3" remains within a cell), I was unable to accomplish this even in Microsoft Word. Since our product's functionality aligns with Microsoft Word, it also cannot achieve this with our product.
Regarding the issue where deleting the "C1" cell removes all bookmarks, I logged it into our bug tracking system with the ticket SPIREDOC-11801. Our dev team will investigate and fix it, once it is resolved or there is any update, I will notify you immediately. Apologize for the inconvenience caused.
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Wed Jan 28, 2026 7:14 am

Dear Marcus,

Regarding issue SPIREDOC-11801, our investigation found that the start markers of your three bookmarks are nested inside the "C1" cell (as shown in the screenshot). Therefore, deleting the C1 cell will cause all subsequent bookmarks to be removed.
Additionally, based on the structure of the table file you are currently using, to delete a bookmark along with the cell (it covers (where the bookmark does not span across rows or columns), we recommend using the following code:
Code: Select all
        Bookmark bookmark = document.getBookmarks().get("C2");
        document.getBookmarks().remove(bookmark);
        table.getFirstRow().getChildObjects().remove(table.getFirstRow().getCells().get(1));
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Wed Jan 28, 2026 8:48 am

Hello Talia!

Thank you for the revised code. I came up to the same solution.
Regarding the placement of the 3 bookmarks, this is something that Microsoft Word does. I had simply marked each of the 3 columns and added a new bookmark.

Does your reply mean, that use have already closed issue SPIREDOC-11801?

Regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Thu Jan 29, 2026 5:43 am

Dear Marcus,

Thank you for your feedback.
As previously mentioned, the cause of issue SPIREDOC-11801 is not due to an internal bug in our product, but rather determined by its inherent structure. Therefore, we intend to close this issue. Thank you for your understanding.
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Thu Jan 29, 2026 8:05 am

Hi Talia!

Before you close SPIREDOC-11801, please note that Microsoft Word does not delete any bookmarks if you delete a table column. This holds true even for the 1st table column.

Kind regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Fri Jan 30, 2026 10:14 am

Hello,

Thank you for your feedback. The difference of deleting the 1st table column is mainly due to the differences in the data structure model processing between our product and Microsoft Word. Below is the content of cell C1 through the underlying XML data. It can be seen that the three bookmarks starts are all marked in cell C1. When deleting C1 cell, our product will delete all bookmarks during processing. And Microsoft Word handles it differently. If we need handle it like Microsoft Word, this adjustment will affect many other functions. Sorry we currently have no plans to adjust it to be the same as Microsoft Word. For your actual usage scenario, if you need to keep bookmarks, you can first obtain the object (bookmark.getBookmarkEnd().deepClone();bookmark.getBookmarkStart().deepClone();) and then insert the corresponding bookmark in the corresponding position. Thank you for your understanding.
C1.png

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1533
Joined: Wed Apr 25, 2018 3:20 am

Tue Mar 17, 2026 9:46 am

Meanwhile I was able to implement a logic that allows me to delete table cells that are part of a bookmark spanning multiple cells (across multiple rows and columns).

However, I have another customer requirement. Now I want to delete a section covered by a bookmark and this section contains a headline that is part of a TOC (table of contents).

In Word I can simply move to the bookmark and press delete and the section including the headline is deleted. I haven't been able to achieve the same behaviour with Spire.Doc for Java.

Here is my sample code:
Code: Select all
Document document = new Document("Test2.docx");
BookmarksNavigator bookmarksNavigator = new BookmarksNavigator(document);
bookmarksNavigator.moveToBookmark("Chapter");
bookmarksNavigator.deleteBookmarkContent(true);
document.updateTableOfContents();
document.saveToFile("Test2.generated.docx");


After executing this code the content covered by the bookmark "Chapter" is deleted but the chapter number is still present. What can I do to get the chapter number being deleted, too?

BTW: Can you explain me the boolean-type parameter of the method "deleteBookmarkContent(boolean saveFormatting)" please? The api documentation isn't very helpful (see https://www.e-iceblue.com/api/java/doc/com-spire-doc-documents/BookmarksNavigator).

Please find attached the test documents.

Kind regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Wed Mar 18, 2026 6:59 am

Hello,

Thank you for your feedback,
Regarding the issue of deleting the bookmark "Chapter", using your code to delete it, the chapter number does still exist. In Microsoft Word, the entire paragraph has been deleted.
Currently, there are some differences in the processing logic between our product and Microsoft's operation. Our development team needs to further evaluate and check whether it can be adjusted to the same processing logic as Microsoft. I have logged this issue using SPIREDOC-11860. Once there is any update, I will provide it to you. Meanwhile, you can achieve the same effect by adjusting the code below first.
Code: Select all
        Document document = new Document("test.docx");
        BookmarksNavigator bookmarksNavigator = new BookmarksNavigator(document);
        Bookmark bk=document.getBookmarks().findByName("Chapter");
        Paragraph para = (Paragraph) bk.getBookmarkStart().getOwner();
        Section sec=(Section)para.getOwner().getOwner();
        bookmarksNavigator.moveToBookmark("Chapter");
        bookmarksNavigator.deleteBookmarkContent(true);
        document.getBookmarks().remove(bk);
            if(para.getText().isEmpty())
            {
                sec.getBody().getChildObjects().remove(para);
            }
        document.updateTableOfContents();
        document.saveToFile("out.docx");

In addition, regarding the parameter deleteBookmarkContent (true), when setting "true", the style of the original bookmark content should be retained. I conducted the following test using the attached documents, but the newly added content did not maintain the style. This phenomenon is abnormal, our Dev team colleagues are also investigating it together. I will let you know as soon as there is any news. Thank you for your understanding.
Code: Select all
        Document document = new Document();
        document.loadFromFile("sample.docx");
        Bookmark bookmark = document.getBookmarks().get("Chapter");

        // get the bookmark start Paragraph
        Paragraph para = (Paragraph) bookmark.getBookmarkStart().getOwner();
        int startIndex = para.getChildObjects().indexOf(bookmark.getBookmarkStart());
        BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(document);
        bookmarkNavigator.moveToBookmark("Chapter");

        // delete bookmark content
        bookmarkNavigator.deleteBookmarkContent(true);

        // add new text
        TextRange tx = new TextRange(document);
        tx.setText("Add new");
        para.getChildObjects().insert(startIndex + 1, tx);

        //save
        document.saveToFile("addnew.docx", FileFormat.Docx);

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1533
Joined: Wed Apr 25, 2018 3:20 am

Return to Spire.Doc

cron