Issue in Inserting a document at a bookmark

Hi,
In our application in a document (parent document) at a bookmark we are supposed to insert another document (child document). This child document is kind of a report from any third party application which will be in the form of a PDF, which in turn will be converted to Word before inserting into the parent document at the given bookmark. Then the converted Word document (child document) will inserted at the bookmark in the parent document. The child document, usually contains data in tabular format.
Now the issue is when we are inserting the child document data is not getting formatted properly. I am here by attaching a document for your reference. In the attached document, Section 1.1 is the parent document in which at the T4 bookmark we have inserted a child document. Child document content is all tables as you can see in the attached document. The entire table content is not visible.
Now if we select one table and center align the table we are able to see the entire content. So can we somehow center align the content of the document (child document) being inserted into a parent document using aspose. So that we can see the entire content.
or any other suggestion/solution for this kind of scenario where we can set something on the document being inserted or format it after the document is inserted into a parent document.
Please advice.
Regards,
Suguna

Hi
Thanks for your inquiry. Could you please attach your input documents and the code here for testing? I will check the issue on my side and provide you more information.
Best regards,

Thanks for the prompt reply. Here are the inputs which you needed.

  1. Attached “15e44b3c1283dd6ee2c7ff2_1307_5.doc” is the parent document where at the T4 bookmark we have to insert a child document
  2. Attached “lack_of_efficacy.doc” is the child document which we want to insert

Below is the code :
Insert Method

public static Document insertDocumentAfterBookMark(Document mainDoc, Document tobeInserted, String bookmark) throws Throwable
{
    // check maindoc
    if (mainDoc == null)
        return null;
    // check to be inserted doc
    if (tobeInserted == null)
        return mainDoc;
    synchronized(mainDoc)
    {
        DocumentBuilder mainDocBuilder = new DocumentBuilder(mainDoc);
        synchronized(tobeInserted)
        {
            // check bookmark and then process
            if (bookmark != null && bookmark.trim().length()> 0)
            {
                Bookmark bm = mainDoc.getRange().getBookmarks().get(bookmark);
                if (bm != null)
                {
                    // Clear the existing content at the bookmark
                    removeBookmarkContent(bm, mainDoc);
                    // Move cursor to bookmark and insert paragraph break
                    mainDocBuilder.moveToBookmark(bookmark);
                    mainDocBuilder.writeln();
                    // Content of tobeInserted document will be inserted after this node
                    Node insertAfterNode = mainDocBuilder.getCurrentParagraph().getPreviousSibling();
                    // insert the document at the bookmark
                    insertDocumentAfterNode(insertAfterNode, mainDoc, tobeInserted);
                }
            }
            else
            {
                // if bookmark is not provided, add the document at the end
                appendDoc(mainDoc, tobeInserted);
            }
        }

    }
    return mainDoc;
}

Removing existing content at that bookmark before inserting the child document

/**
    * Deletes existing content at the given bookmark in the given document
    *
    * @param bookmark
    * @param doc
    * @throws Throwable
    */
public static void removeBookmarkContent(Bookmark bookmark, Document doc) throws Throwable
{
    // We need to store other bookmark nodes here, to move them away from the removed area.
    Set bookmarkNames = new HashSet();
    Map bookmarkStarts = new HashMap();
    Map bookmarkEnds = new HashMap();
    ArrayList nodesToRemove = new ArrayList();
    BookmarkStart bookmarkStart = bookmark.getBookmarkStart();
    BookmarkEnd bookmarkEnd = bookmark.getBookmarkEnd();
    Paragraph lastParagraph = doc.getLastSection().getBody().getLastParagraph();
    Node node = seekFirstNodeOfBookmarkRange(bookmarkStart, doc);
    findParagraphNextAfterBookmark(bookmarkEnd, doc);
    // Iterate over all nodes that contain or are between bookmark start and end nodes.
    while (node != bookmarkEnd)
    {
        node = node.nextPreOrder(doc);
        // BookmarkStart/BookmarkEnd are saved to be handled separately later.
        // All other nodes are collected as candidates for removal.
        if (!storeIfBookmark(bookmarkNames, bookmarkStarts, bookmarkEnds, node))
        {
            nodesToRemove.add(node);
        }
    }
    boolean hasNodesToRemove = true;
    while (hasNodesToRemove)
    {
        hasNodesToRemove = false;
        for (int i = 0; i <nodesToRemove.size(); i++)
        {
            Node nodeToRemove = (Node) nodesToRemove.get(i);
            // Skip already removed nodes.
            if (nodeToRemove.getParentNode() == null)
                continue;
            // Skip nodes that have child nodes.
            if (nodeToRemove.isComposite() && ((CompositeNode) nodeToRemove).hasChildNodes())
                continue;
            // Do not remove node if it is the last paragraph in the document.
            if (nodeToRemove == lastParagraph)
                continue;
            // Remove node.
            nodeToRemove.remove();
            // If at least one node was removed in loop, then the loop will be repeated.
            hasNodesToRemove = true;
        }
    }
}
    
/**
    * Returns the first encountered node in Bookmark range
    *
    * @param bookmarkStart
    * @param doc
    * @return Node
    * @throws Throwable
    */
private static Node seekFirstNodeOfBookmarkRange(BookmarkStart bookmarkStart, Document doc) throws Throwable
{
    Node node = bookmarkStart;
    // Bookmark nodes located immediately before start of our bookmark
    // should also be included in the removal process.
    do {
        node = node.previousPreOrder(doc);
    } while (isBookmarkNode(node));
    // Look back from the bookmark start node to include containing nodes into removal process.
    while (node.isComposite())
    {
        Node prevNode = node.previousPreOrder(doc);
        if (prevNode == null)
        {
            break;
        }
        else
        {
            node = prevNode;
        }
    }
    return node;
}
    
/**
    * Returns the next paragraph of the bookmark
    *
    * @param bookmarkEnd
    * @param doc
    * @return Paragraph
    * @throws Throwable
    */
private static Paragraph findParagraphNextAfterBookmark(BookmarkEnd bookmarkEnd, Document doc) throws Throwable
{
    // Find the paragraph that is next to removed bookmark range.
    // It will be used to move all bookmark start/end nodes belonging to bookmarks overlapping our bookmark,
    // so that they will be preserved after this bookmark removal.
    Paragraph para;
    Node node = bookmarkEnd;
    // It can be that the paragraph containing bookmark end node if the last paragraph in the bookmark range
    // contains other nodes beside BookmarkEnd or is the last unremovable paragraph in the document.
    if (node.getNextSibling() != null ||
            node.getParentNode() == doc.getLastSection().getBody().getLastParagraph())
    {
        para = (Paragraph) bookmarkEnd.getParentNode();
    } // Or it can be the paragraph next to it.
    else {
        while (node.getNodeType() != NodeType.PARAGRAPH)
        {
            node = node.nextPreOrder(doc);
        }
        para = (Paragraph) node;
    }
    return para;
}
    
/**
    * Returns true if the given node is a bookmark node else returns false
    *
    * @param node
    * @return boolean
    * @throws Throwable
    */
private static boolean isBookmarkNode(Node node) throws Throwable
{
    return (node.getNodeType() == NodeType.BOOKMARK_START) ||
            (node.getNodeType() == NodeType.BOOKMARK_END);
}
    
/**
    * Returns true if either of bookmark start or bookmark end nodes are stored else
    * returns false
    *
    * @param bookmarkNames
    * @param bookmarkStarts
    * @param bookmarkEnds
    * @param node
    * @return boolean
    * @throws Throwable
    */
private static boolean storeIfBookmark(Set bookmarkNames, Map bookmarkStarts, Map bookmarkEnds, Node node) throws Throwable
{
    if (node.getNodeType() == NodeType.BOOKMARK_START)
    {
        BookmarkStart bookmarkStart = (BookmarkStart) node;
        bookmarkNames.add(bookmarkStart.getName());
        bookmarkStarts.put(bookmarkStart.getName(), bookmarkStart);
        return true;
    }
    else if (node.getNodeType() == NodeType.BOOKMARK_END)
    {
        BookmarkEnd bookmarkEnd = (BookmarkEnd) node;
        bookmarkNames.add(bookmarkEnd.getName());
        bookmarkEnds.put(bookmarkEnd.getName(), bookmarkEnd);
        return true;
    }
    return false;
}

Insert doc after node method

/**
    * Inserts content of the external document after the specified node.
    * Section breaks and section formatting of the inserted document are
    * ignored.Node in the destination document
    * after which the content should be inserted.This node should be a block
    * level node (paragraph or table).
    */
public static void insertDocumentAfterNode(Node insertAfterNode, Document mainDoc, Document srcDoc) throws Throwable
{
    synchronized(srcDoc)
    {
        synchronized(insertAfterNode)
        {
            // Make sure that the node is either a pargraph or table.
            if ((insertAfterNode.getNodeType() != NodeType.PARAGRAPH) &
                    (insertAfterNode.getNodeType() != NodeType.TABLE))
                throw new Exception("The destination node should be either a paragraph or table.");
            // We will be inserting into the parent of the destination paragraph.
            CompositeNode dstStory = insertAfterNode.getParentNode();
            // Remove empty paragraphs from the end of document
            while (null != srcDoc.getLastSection().getBody().getLastParagraph() &&
                    !srcDoc.getLastSection().getBody().getLastParagraph().hasChildNodes())
            {
                srcDoc.getLastSection().getBody().getLastParagraph().remove();
            }
            NodeImporter importer = new NodeImporter(srcDoc, mainDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING);
            // Loop through all sections in the source document.
            int sectCount = srcDoc.getSections().getCount();
            for (int sectIndex = 0; sectIndex <sectCount; sectIndex++)
            {
                Section srcSection = srcDoc.getSections().get(sectIndex);
                // Loop through all block level nodes (paragraphs and tables) in the body of the section.
                int nodeCount = srcSection.getBody().getChildNodes().getCount();
                for (int nodeIndex = 0; nodeIndex <nodeCount; nodeIndex++)
                {
                    Node srcNode = srcSection.getBody().getChildNodes().get(nodeIndex);
                    Node newNode = importer.importNode(srcNode, true);
                    dstStory.insertAfter(newNode, insertAfterNode);
                    insertAfterNode = newNode;
                }
            }
        }
    }
}
/**
    * Appends a document to another.
    * @param dstDoc--Destination document
    * @param srcDoc--Source document
    * @param includeSection - if true the sections from srcDoc will be copied as it is, else only the internal nodes will be copied
    * @throws Throwable
    */
public static void appendDoc(Document dstDoc, Document srcDoc, boolean includeSection)
        throws Throwable
{
    synchronized(srcDoc)
    {
        synchronized(dstDoc)
        {
            // Loop through all sections in the source document.
            // Section nodes are immediate children of the Document node so we can
            // just enumerate the Document.
            if (includeSection)
            {
                for (Section srcSection: srcDoc.getSections())
                {
                    Node dstNode = dstDoc.importNode(srcSection, true,
                            ImportFormatMode.USE_DESTINATION_STYLES);
                    dstDoc.appendChild(dstNode);
                }
            }
            else
            {
                // find the last paragraph of the last section
                Node node = dstDoc.getLastSection().getBody().getLastParagraph();
                    
                if (node == null)
                {
                    node = new Paragraph(srcDoc);
                    dstDoc.getLastSection().getBody().appendChild(node);
                }
                    
                if ((node.getNodeType() != NodeType.PARAGRAPH) &
                        (node.getNodeType() != NodeType.TABLE))
                {
                    throw new Exception("Use appendDoc(dstDoc, srcDoc, true) instead of appendDoc(dstDoc, srcDoc, false)");
                        
                }
                insertDocumentAfterNode(node, dstDoc, srcDoc);
            }
        }
    }
}
/**
    * Same as appendDoc(dstDoc, srcDoc, true)
    * @param dstDoc
    * @param srcDoc
    * @throws Throwable
    */
public static void appendDoc(Document dstDoc, Document srcDoc) throws Throwable
{
    appendDoc(dstDoc, srcDoc, true);
}

Do let me know if you need anything else.

Hi
Thank you for additional information. I think in your case you can use the code like the following to center the table:

// Open the document.
Document dstDoc = new Document("15e44b3c1283dd6ee2c7ff2_1307_5.doc");
Document srcDoc = new Document("lack_of_efficacy.doc");
// Get all rows
NodeCollection rows = srcDoc.GetChildNodes(NodeType.Row, true);
// Loop through all rows.
foreach(Row row in rows)
{
    row.RowFormat.Alignment = RowAlignment.Center;
}
// And then insert srcDoc document in to the dstDoc document

Hope this helps.
Best regards,

Thanks a lot! Its working.