Problems with NodeImporter using ImportFormatMode KeepSourceFormatting


#1

Hi,

we have some problems with KeepSourceFormatting option when importing textboxes from one document into another.
Please have a look on the three attached Documents: Aspose_NodeImporter_Example.zip (73.7 KB)
The source document “DocToImport3.docx” has some equal formatted Text in paragraphs and textboxes.
The test is set to “Normal” style which is set to “Times new Roman, Size 10”.
The target document (DocBase2.docx) has a different setting for “Normal” (Calibri, size 11).
After import with option KeepSourceFormatting set using the code below the resulting document (ResultP2.docx) is showing the paragraph text with formatting of source document as expected, but the textboxes are in new “Normal” style.

Best regards
Christian

Code:

    public void AsposeImportDocInDoc()
    {
        Aspose.Words.License lic = new Aspose.Words.License();
        lic.SetLicense("Aspose.Total.lic");

        var docBase = new Aspose.Words.Document(@"C:\@@tmp\DocBase2.docx");
        var docToImport = new Aspose.Words.Document(@"C:\@@tmp\DocToImport3.docx");

        //Simualtion
        var id = Guid.NewGuid();
        List<string> fields = new List<string>() { "Dokumentinhalt" };
        List<object> fieldsdata = new List<object>() { id };
        docBase.MailMerge.Execute(fields.ToArray(), fieldsdata.ToArray());


        Aspose.Words.Node insertAfterNode = null;
        //We need to find placeholder for content
        {
            foreach (Section section in docBase.Sections)
            {
                if (section.Body != null)
                {
                    insertAfterNode = section.Body.ChildNodes.ToArray().ToList().Find(x => x.ToString(SaveFormat.Text).Contains(id.ToString()));
                    if (insertAfterNode != null)
                        break;
                }
            }
            if (insertAfterNode == null)
                insertAfterNode = docBase.LastSection.Body.LastChild;
        }

        InsertDocument(insertAfterNode, docToImport);
       
        docBase.Clone().Save(@"C:\@@tmp\ResultP2.docx");
    }


    /// <summary>
    /// Inserts content of the external document after the specified node.
    /// Section breaks and section formatting of the inserted document are ignored.
    /// </summary>
    /// <param name="insertAfterNode">Node in the destination document after which the content 
    /// should be inserted. This node should be a block level node (paragraph or table).</param>
    /// <param name="srcDoc">The document to insert.</param>
    static void InsertDocument(Node insertAfterNode, Document srcDoc)
    {
        // Make sure that the node is either a paragraph or table.
        if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) &
            (!insertAfterNode.NodeType.Equals(NodeType.Table)))
            throw new ArgumentException("The destination node should be either a paragraph or table.");

        // We will be inserting into the parent of the destination paragraph.
        CompositeNode dstStory = insertAfterNode.ParentNode;

        // This object will be translating styles and lists during the import.
        NodeImporter importer =
            new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting);

        // Loop through all sections in the source document.
        foreach (Section srcSection in srcDoc.Sections.OfType<Section>())
        {
            // Loop through all block level nodes (paragraphs and tables) in the body of the section.
            foreach (Node srcNode in srcSection.Body)
            {
                // Let's skip the node if it is a last empty paragraph in a section.
                if (srcNode.NodeType.Equals(NodeType.Paragraph))
                {
                    Paragraph para = (Paragraph)srcNode;
                    if (para.IsEndOfSection && !para.HasChildNodes)
                        continue;
                }

                // This creates a clone of the node, suitable for insertion into the destination document.
                Node newNode = importer.ImportNode(srcNode, true);

                // Insert new node after the reference node.
                dstStory.InsertAfter(newNode, insertAfterNode);
                insertAfterNode = newNode;
            }
        }
    }

#2

@Chris2Stein,

We tested the scenario and have managed to reproduce the same problem on our end. For the sake of correction, we have logged this problem in our issue tracking system. The ID of this issue is WORDSNET-18202. We will further look into the details of this problem and will keep you updated on the status of correction. We apologize for your inconvenience.


#3

The issues you have found earlier (filed as WORDSNET-18202) have been fixed in this Aspose.Words for .NET 19.4 update and this Aspose.Words for Java 19.4 update.


#4

Sorry, but it is still not working for me with Aspose.words 19.4.

See KeepSourceFormatting.zip (70.5 KB)
.
The source document “DocToImport3.docx” (Paragraph and textbox) is using “Normal” style which is set to “Times new Roman, Size 10”.
The target document (DocBase2.docx) has a different setting for “Normal” (Calibri, size 11).
After import with option KeepSourceFormatting using the code above the resulting document (ResultP2.docx) is showing the paragraph text with formatting of source document as expected, but the textboxes are still in Calibri, size 11 which is “Normal” style of target document.

Best regards
Christian


#5

@Chris2Stein,

We have added a new ImportFormatOptions class for more flexible control over importing tasks. Please check Aspose.Words for .NET 19.4 Release Notes.

Please also try the following method. Hope, this helps.

//////////////////
/// <summary>
/// Inserts content of the external document after the specified node.
/// Section breaks and section formatting of the inserted document are ignored.
/// </summary>
/// <param name="insertAfterNode">Node in the destination document after which the content 
/// should be inserted. This node should be a block level node (paragraph or table).</param>
/// <param name="srcDoc">The document to insert.</param>
static void InsertDocument(Node insertAfterNode, Document srcDoc)
{
    // Make sure that the node is either a paragraph or table.
    if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) &
        (!insertAfterNode.NodeType.Equals(NodeType.Table)))
        throw new ArgumentException("The destination node should be either a paragraph or table.");

    // We will be inserting into the parent of the destination paragraph.
    CompositeNode dstStory = insertAfterNode.ParentNode;

    // This object will be translating styles and lists during the import.
    ImportFormatOptions opts = new ImportFormatOptions();
    opts.IgnoreTextBoxes = false;

    NodeImporter importer =
        new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting, opts);

    // Loop through all sections in the source document.
    foreach (Section srcSection in srcDoc.Sections.OfType<Section>())
    {
        // Loop through all block level nodes (paragraphs and tables) in the body of the section.
        foreach (Node srcNode in srcSection.Body)
        {
            // Let's skip the node if it is a last empty paragraph in a section.
            if (srcNode.NodeType.Equals(NodeType.Paragraph))
            {
                Paragraph para = (Paragraph)srcNode;
                if (para.IsEndOfSection && !para.HasChildNodes)
                    continue;
            }

            // This creates a clone of the node, suitable for insertion into the destination document.
            Node newNode = importer.ImportNode(srcNode, true);

            // Insert new node after the reference node.
            dstStory.InsertAfter(newNode, insertAfterNode);
            insertAfterNode = newNode;
        }
    }
}

#6

Hi,

Yes, it worked!

Thank you very much!