Reading custom styles from .DOTX file and then applying to Text between special tags

I want to generate TOC for an existing word document. Aspose should be able to scan the whole document and find all the headings and then generate TOC at the begining of the page!

We will add a "temp special character" to all the headings in the document so that Aspose can find all the headings in the document just by finding the special character!

I have some documents in .rtf format that do not have the styles applied for the headings and the document doesn’t have the TOC. I also have an existing DOTX file which has the custom styles defined for all the headings in the document.

Our document will have a “Special tags” embedding all the text for which we need to apply the style as heading (read the style from the DOTX file). And then finally applying TOC.

Here is what Aspose should do:

  1. Scan the document (.rtf in this case) and find the “special tags”.

  2. Where ever the special tags (Start and End) are found, apply the custom styles to only the content by reading the custom style from the DOTX file corresponding to the tag.

  3. Remove the Start and End tags between Start and End tags,

Eg:

a. Start-AA-Heading1EMPLOYEREnd-AA-Heading1

Here, Start-AA-Heading1 and End-AA-Heading1 are the start and end tags. We need to apply the style Cust_AA_Heading1 style (available in .DOTX file) to the text “EMPLOYERE” and delete the Start-AA-Heading1 and End-AA-Heading1 texts from the document.

b. Start-AA-Heading2EXECUTION PAGEEnd-AA-Heading2

Similarly, we need to apply the Cust_AA_Heading2 style (available in .DOTX file) to the text “Heading2EXECUTION PAGE” and then delete the texts Start-AA-Heading2 and PAGEEnd-AA-Heading2 from the document.

  1. Then finally run the TOC and save the file as .doc file. ( we know this step works)

I have attached the sample .rtf and .dotx file. Please provide the sample code to read the styles from .dotx file, traversing the input (.rtf) file and find out the start and end tags to apply the custom styles for the content between the tags, and then finally deleting those tags from the document.

If you could provide or share some code base which addresses the similar scenario as mine, It would be greatfuil. I already have the aspose license.

My sample code is given below:

// Load an existing Word document in memory
Document _pAsposeDocument = new Document("C:\\AA_Input.rtf");
//set the full file path of the customStyles file related to the document
_pAsposeDocument.AttachedTemplate = "C:\\AA_Style_Template.dotx";
//import custom styles from .DOTX document into the BIP document 
Document CustomStylesDoc = new Document(_pAsposeDocument.AttachedTemplate);
foreach (Style srcStyle in CustomStylesDoc.Styles)
{
    if (!srcStyle.BuiltIn)
        _pAsposeDocument.Styles.AddCopy(srcStyle);
}

//HERE , I want to get the text between the start and End tags and then find out the corresponding style in the document and apply to the content between the tags. How can I achieve it? How to find the StyleIdentifier value for the custom style that is added from the .dotX file.

//Apply TOC
// Create a document builder to insert content with into document.
DocumentBuilder builder = new DocumentBuilder(_pAsposeDocument);
// Insert a table of contents at the beginning of the document.
builder.MoveToDocumentStart();
builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
// Start the actual document content on the second page.
builder.InsertBreak(BreakType.PageBreak);
// Call the method below to update the TOC.
_pAsposeDocument.UpdateFields();
//Save the file as .doc _pAsposeDocument.Save("C:\\AA_Output.doc");

Hi Komal,

Thanks for your inquiry. Sure, please try run the following code which I believe will help in achieving what you’re looking for:

// Load an existing Word document in  memory
Document _pAsposeDocument = new Document(@"C:\AA_Input\AA_Input.rtf");
//set the full file path of the customStyles file related to the document
_pAsposeDocument.AttachedTemplate = @"C:\AA_Input\AA_Style_Template.dotx";
Document CustomStylesDoc = new Document(_pAsposeDocument.AttachedTemplate);
foreach (Style srcStyle in CustomStylesDoc.Styles)
{
    if (!srcStyle.BuiltIn)
        _pAsposeDocument.Styles.AddCopy(srcStyle);
}
NodeCollection paragraphs = _pAsposeDocument.GetChildNodes(NodeType.Paragraph, true);
foreach (Paragraph para in paragraphs)
{
    string styleId = "";
    foreach (Run run in para.Runs)
    {
        if (run.Text.Contains("Start-AA-Heading"))
        {
            if (run.Text.Contains("End-AA-Heading"))
            {
                run.Text = run.Text.Replace("Start-AA-Heading", "");
                run.Text = run.Text.Replace("End-AA-Heading", "");
                styleId = run.Text[0].ToString();
                run.Text = run.Text.Remove(0, 1);
                run.Text = run.Text.Remove(run.Text.Length - 1, 1);
            }
            else
            {
                // If start and end markers are spanned across multiple Runs
                // Please loop through the remaining Runs until you find the Run
                // that contains the end marker
                // Extract the styleId
                // Remove the First and Last Run nodes when finished
            }
        }
    }
    if (styleId == "1")
        para.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
    if (styleId == "2")
        para.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
}
//Apply TOC
// Create a document builder to insert content with into document.
DocumentBuilder builder = new DocumentBuilder(_pAsposeDocument);
// Insert a table of contents at the beginning of the document.
builder.MoveToDocumentStart();
builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
// Start the actual document content on the second page.
builder.InsertBreak(BreakType.PageBreak);
// Call the method below to update the TOC.
_pAsposeDocument.UpdateFields();

Please let me know if I can be of any further assistance.

Best regards,

Hi,

I am able to apply the custom styles from external .DOTX file for the text embedded between start and end tag, using the below code. However I still have few issues and also need your suggestion on some features. I have attached the all the input and output documents for your reference. Please use the latest files for validating changes from your end.

// Load an existing Word document in memory
Document _pAsposeDocument = new Document(@"C:\AA_Input\AA_Input.rtf");
//set the full file path of the customStyles file related to the document
_pAsposeDocument.AttachedTemplate = @"C:\AA_Input\AA_Style_Template.dotx";
List<string> customStylesNames = new List<string>();
//1. Import custom styles from .DOTX document into the BIP document 
Document CustomStylesDoc = new Document(_pAsposeDocument.AttachedTemplate);
foreach (Style srcStyle in CustomStylesDoc.Styles)
{
    if (!srcStyle.BuiltIn)
        _pAsposeDocument.Styles.AddCopy(srcStyle);
    //if the style is a custom style, then add it to the list
    if (srcStyle.Name.Contains(CustomStyleType))
        customStylesNames.Add(srcStyle.Name);
}
//2. Apply custom Styles to texts that exist between special Start and End tags.
NodeCollection paragraphs = _pAsposeDocument.GetChildNodes(NodeType.Paragraph, true);
foreach (String custStyleName in customStylesNames)
{
    String StartTagName = tempName.Replace("Cust", "Start");
    String EndTagName = tempName.Replace("Cust", "End");
    foreach (Paragraph para in paragraphs)
    {
        bool isCustomText = false;
        foreach (Run run in para.Runs)
        {
            //Remove the Start and End Tags if present.
            if (run.Text.Contains(StartTagName))
            {
                run.Text = run.Text.Replace(StartTagName, "");
                isCustomText = true; //if we find just the start tag, its enough..treat it as custom
            }
            if (run.Text.Contains(EndTagName))
            {
                run.Text = run.Text.Replace(EndTagName, "");
            }
        }
        //Apply the custom style that was imported from the template
        if (isCustomText == true)
            para.ParagraphFormat.Style = _pAsposeDocument.Styles[custStyleName];
    }
}
//3. Create a document builder to insert content with into document.
DocumentBuilder builder = new DocumentBuilder(_pAsposeDocument);
// Insert a table of contents at the beginning of the document.
builder.MoveToDocumentStart();
builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
// Start the actual document content on the second page.
builder.InsertBreak(BreakType.PageBreak);
// Call the method below to update the TOC.
_pAsposeDocument.UpdateFields();
// 4. Save the final document to disk.
_pAsposeDocument.Save(@"C:\AA_Input\AA_Output.doc", SaveFormat.Doc);

Issues Noticed:

  1. The AA_Output.doc has 4 custom Styles, When I added only two custom styels from the .DOTX file.
    a. Cust_AA_Heading1 - present in DOTX file
    b. Cust_AA_Heading2 - present in DOTX file
    c. Cust_AA_Heading1_0 - Not present in DOTX file.How did it get added
    d. Cust_AA_Heading2_0 - Not present in DOTX file. How did it get added

  2. Only the first heading 1.01 is currently aligned in the document. Other number 1.02 , 1.03 have more spacing. when I selected text with 1.02 heading, the Custom_AA_Heading1 style is not higlighted in the document, Which means that the custom style is not applied. When I applied the style manually, by selecting the row and then clicking on the Custom_AA_Heading1, 1.02 is alligned corrrectly with 1.01. Why the custom style is not applied for all the heading?

1.01 PLAN INFORMATION

1.02 EMPLOYER

  1. I want to insert the TOC in 2nd page after the main title page. How can I achieve it.

  2. I don’t want to have the empty line or any line spacing between the TOC lines. How to do it.

  3. I want to have all the TOC in Bold color.

Please find attached the TOC.doc for reference. I want to have the TOC styles similar to it. Please suggest.


For your information , The other code that I used to find the StartTag, and then apply the custom styles and then to remove and start and end tag is given below… But, both are giving the same results… Please help us to resolve the above issues.

//2. Apply custom Styles to texts that exists between special Start and End tags.
NodeCollection paragraphs = _pAsposeDocument.GetChildNodes(NodeType.Paragraph, true);
foreach (String custStyleName in customStylesNames)
{
    String StartTagName = custStyleName.Replace("Cust", "Start");
    foreach (Paragraph para in paragraphs)
    {
        if (para.ToString(SaveFormat.Text).Contains(StartTagName))
            para.ParagraphFormat.Style = _pAsposeDocument.Styles[custStyleName];
    }
}
//3.Remove the Start and EndTags, If present in the entire document.
foreach (String custStyleName in customStylesNames)
{
    String StartTagName = custStyleName.Replace("Cust", "Start");
    String EndTagName = custStyleName.Replace("Cust", "End");
    _pAsposeDocument.Range.Replace(StartTagName, "", false, false);
    _pAsposeDocument.Range.Replace(EndTagName, "", false, false);
}

Hi Komal,

Thanks for your inquiry.

  1. While using the latest version of Aspose.Words i.e. 13.5.0, I managed to reproduce this issue on my side. I have logged the following issue in our bug tracking system.

WORDSNET-8375: StyleCollection.AddCopy method adds a style twice in destination document

Your thread has also been linked to this issue and you will be notified as soon as it is resolved. Sorry for the inconvenience.

  1. I am working over this part of your query and will get back to you soon.

  2. Please create a separate section just to contain the Table Of Contents as follows. In this case the first Section will contain the Title Content, second Section will contain the TOC field and the third Section will contain the rest of the content.

Document doc = new Document(@"C:\Temp\AA_Input.rtf");
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToSection(1);
// Insert TOC field here
builder.InsertBreak(BreakType.SectionBreakNewPage);
doc.Save(@"C:\Temp\out.doc");
  1. and 5) Please try run the following code snippet.
NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);
foreach (Paragraph paragraph in paragraphs)
{
    if (paragraph.Range.Text.Contains("_Toc"))
    {
        // Chnage Font formatting of each TOC item
        foreach (Run run in paragraph.Runs)
            run.Font.Color = Color.Red;
        // Remove vertical spacing between TOC Paragraphs
        paragraph.ParagraphFormat.SpaceBefore = 0;
        paragraph.ParagraphFormat.SpaceAfter = 0;
    }
}

Best regards,

Hi Awais Hafeez,

Thanks for you assistance on this.

Will look forward to your inputs on issue 2 and also will be watching WORDSNET-8375.

Regarding Issue 2, I have noticed another problem, When I applied CUSTOM_AA_Heading1 to many sections, After adding the number 1.09, it is creating the next numbers as 1.010, 1.011, 1.012 etc… I want these numbers as 1.10, 1.11, 1.12 etc… I want the numbering exactly simlar to how it is in TOC.doc. Please verify this when you are looking into issue 2.

Also ( Regarding issue 4 and 5)), I need to apply ‘Times New Roman’ font with size and 10 and BOLD to all TOC content. I am able to set the size and BOLD to TOC, But I am not able to apply the font 'Times New Roman" to TOC content at run level or paragraph level. How can I acheive this… I want the style similar to TOC.doc.

// Chnage Font formatting of each TOC item to: Times New Roman, 10, Bold
foreach (Run run in paragraph.Runs)
{
    run.Font.Bold = true;
    run.Font.Size = 10;
    // run.Font.Style.Name = "Times New Roman"; // Not working.
}
paragraph.ParagraphFormat.Style = _pAsposeDocument.Styles["Times New Roman"]; //Not working

Please find attached the updated input file AA_Input.rtf with more heading1 sections.

Hi,

Do you have any updates/suggestions on the two issues(still pending) that I reported in earlier posts.

Hi Komal,

Thanks for your inquiry and sorry for the delayed response.

Komal:

2. Only the first heading 1.01 is currently aligned in the document. Other number 1.02 , 1.03 have more spacing. when I selected text with 1.02 heading, the Custom_AA_Heading1 style is not higlighted in the document, Which means that the custom style is not applied. When I applied the style manually, by selecting the row and then clicking on the Custom_AA_Heading1, 1.02 is alligned corrrectly with 1.01. Why the custom style is not applied for all the heading?

1.01 PLAN INFORMATION

1.02 EMPLOYER

I tested this scenario and have managed to reproduce the same problem on my side. For the sake of correction, I have logged this problem in our issue tracking system as WORDSNET-8413. Our development team will further look into the details of this problem and we will keep you updated on the status of correction. We apologize for your inconvenience.

Komal:

Regarding Issue 2, I have noticed another problem, When I applied CUSTOM_AA_Heading1 to many sections, After adding the number 1.09, it is creating the next numbers as 1.010, 1.011, 1.012 etc… I want these numbers as 1.10, 1.11, 1.12 etc… I want the numbering exactly simlar to how it is in TOC.doc. Please verify this when you are looking into issue 2.

This appears to be an expected behaviour; you can confirm this by manually selecting the paragraph(s) and then applying the ‘Cust-AA-Heading1’ style to them using Microsoft Word.

Komal:

But I am not able to apply the font 'Times New Roman" to TOC content at run level or paragraph level.

You can simply specify the font name to the run using it’s Font.Name property as follows:

foreach (Run run in paragraph.Runs)
{
    run.Font.Color = Color.Red;
    run.Font.Bold = true;
    run.Font.Size = 10;
    run.Font.Name = "Times New Roman";
}

I hope, this helps.

Best regards,

Hi Awais Hafeez,

Thanks for your response. I am able to set the Times Roman Font to TOC.

Also, The numbering issue with Headings ( 1.010, 1.011) is resolved. It was related to style Cust-AA_Heading1. Please find the attached new .DOTX file with the correction. Now it will create the numbers as 1.09, 1.10, 1.11 etc…

I will look forward to two issues that are releated to this post, and are logged in your bug tracking system .

  1. WORDSNET-8375: StyleCollection.AddCopy method adds a style twice in destination document

  2. WORDSNET-8413:

Issue WORDSNET-8413 is very critical to us and its a show stopper for our delivery.

Hi Komal,

Thanks for the additional information.

Regarding WORDSNET-8413, I think, you can simply use the following correction in your code here to be able to achieve what you’re looking for:

//2. Apply custom Styles to texts that exist between special Start and End tags.
NodeCollection paragraphs = _pAsposeDocument.GetChildNodes(NodeType.Paragraph, true);
foreach (String custStyleName in customStylesNames)
{
    String StartTagName = tempName.Replace("Cust", "Start");
    String EndTagName = tempName.Replace("Cust", "End");
    foreach (Paragraph para in paragraphs)
    {
        bool isCustomText = false;
        foreach (Run run in para.Runs)
        {
            //Remove the Start and End Tags if present.
            if (run.Text.Contains(StartTagName))
            {
                run.Text = run.Text.Replace(StartTagName, "");
                isCustomText = true; //if we find just the start tag, its enough..treat it as custom
            }
            if (run.Text.Contains(EndTagName))
            {
                run.Text = run.Text.Replace(EndTagName, "");
            }
        }
        //Apply the custom style that was imported from the template
        if (isCustomText == true)
        {
            para.ParagraphFormat.ClearFormatting();
            para.ParagraphFormat.Style = _pAsposeDocument.Styles[custStyleName];
        }
    }
}

I hope, this helps.

Best regards,

Hi Komal,

Regarding WORDSNET-8375, it is to update you that our development team has completed the analysis of this issue and has come to a conclusion that they won’t be able to implement the fix to your issue. Most likely, your issue will be closed with ‘‘Won’t Fix’’ resolution.

The problem occurs because all the styles in your document that have duplicates are having a ‘linked style’. By default if AddCopy is requested on a style that has a linked style, both of those styles are copied. So, in your case when “Cust-AA-Heading2” is copied, linked character style “Cust-AA-Heading1Char” is also copied. But when you add “Cust-AA-Heading1Char” again using AddCopy method, Aspose.Words duplicates this existing style with _0 suffix. The simple way to fix this is to check if a style already exists in the document before doing AddCopy. Please see the following sample code:

Document doc = new Document(@"C:\Temp\AA_Input.rtf");
doc.AttachedTemplate = @"C:\Temp\AA_Style_Template.dotx";
Document CustomStylesDoc = new Document(doc.AttachedTemplate);
foreach (Style srcStyle in CustomStylesDoc.Styles)
{
    if (!srcStyle.BuiltIn)
    {
        Style style = doc.Styles[srcStyle.Name];
        if (style == null)
            doc.Styles.AddCopy(srcStyle);
    }
}

I hope, this helps.

Best regards,

Hi,

Thanks for your workaruond solution for issues WORDSNET-8375 and WORDSNET-8413. Both worked for me.

I have one outstanding issue related to this thread reagarding the TOC. All the inputs that you provided me regarding the TOC worked well for me. However, when I opened the modified file and MSWORD-> select the TOC content -> Right mouse click -> click update Field -> choose “Update entire table”, The TOC is loosing its font, style and paragraph spacing.

How can presevere this styling information on updating the TOC in msword. Please let me know.

Before updating the table , Styles added through aspose :-> Times New Roman, Size 10, Bold, Paragraph line spacing = single, Indentation Special = Hanging by 0.46, General Allignment = Justified.

After updating the TOC in MS WORD -> Times New Roman, size 11, Non Bold, Paragraph line spacing Multiple at 1.15, Indentation Special = None, General Allignment = Left

The code snippet, that I am using to add TOC is:

//1.Create a document builder to insert content with into document.
Document _pAsposeDocument = new Document(@"C:\AA_Input.rtf");
DocumentBuilder builder = new DocumentBuilder(_pAsposeDocument);
// Revert to default formatting.
builder.Font.ClearFormatting();
//2. Insert a table of contents at the 2nd page of the document. 2nd page is already blank in the original doc
builder.MoveToSection(1);
//Start the actual document content on the second page.
//builder.InsertBreak(BreakType.PageBreak); //no need to insert empty page as the orignal .rtf file has empty page reserved for TOC
//Specify font formatting before adding text.
builder.Font.Size = 10;
builder.Font.Bold = true;
builder.Font.Color = Color.Black;
builder.Font.Name = "Times New Roman";
builder.ParagraphFormat.Alignment = ParagraphAlignment.Justify;
//Write the heading "TABLE OF CONTENTS"
builder.Write("TABLE OF CONTENTS");
builder.InsertBreak(BreakType.LineBreak);
builder.InsertBreak(BreakType.LineBreak);
//Insert the TOC
builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
//3. The newly inserted table of contents will be initially empty.
// It needs to be populated by updating the fields in the document.
_pAsposeDocument.UpdateFields();
//4. TOC styling: To have all the TOC content in Bold, TIme New Roman Font and to remove the empty lines between the TOC lines.
NodeCollection paragraphs = _pAsposeDocument.GetChildNodes(NodeType.Paragraph, true);
foreach (Paragraph paragraph in paragraphs)
{
    if (paragraph.Range.Text.Contains("_Toc"))
    {
        // Change Font formatting of each TOC item to: Times New Roman, 10, Bold
        foreach (Run run in paragraph.Runs)
        {
            run.Font.Bold = true;
            run.Font.Size = 10;
            run.Font.Color = Color.Black;
            run.Font.Name = "Times New Roman";
        }
        // Remove vertical spacing between TOC Paragraphs
        paragraph.ParagraphFormat.SpaceBefore = 0;
        paragraph.ParagraphFormat.SpaceAfter = 0;
        //Having Single line spacing
        paragraph.ParagraphFormat.LineSpacingRule = LineSpacingRule.Multiple;
        paragraph.ParagraphFormat.LineSpacing = 12; // One line equals 12 points.
        //Set the allignment
        paragraph.ParagraphFormat.KeepTogether = true;
        paragraph.ParagraphFormat.Alignment = ParagraphAlignment.Justify;
        //To set the hanging indent to 0.5
        paragraph.ParagraphFormat.LeftIndent = 33;
        paragraph.ParagraphFormat.FirstLineIndent = -33;
    }
}

Also, I want to read one of the Tracking ID(**53951 - 1370344009) * *present in the footer of the document.Please find the attached AA_Input.doc.I tried to read it using the below code.but, it is giving the some other value with-in the footer itself.Could you plase help me to fetch this green text.

public static string GetTrackingID(String DocPath)
{
    String strTrackID = String.Empty;
    Document Doc = new Document(DocPath);
    HeaderFooter pf = Doc.FirstSection.HeadersFooter[HeaderFooterType.FooterPrimary];
    if (pf != null)
    {
        Run run = pf.Paragraphs[1].LastChild as Run;
        if (run != null)
            strTrackID = run.Text;
    }
    return strTrackID;
}

Hi Komal,

Thanks for your inquiry.

Komal:

when I opened the modified file and MSWORD-> select the TOC content -> Right mouse click -> click update Field -> choose “Update entire table”, The TOC is loosing its font, style and paragraph spacing.

This is the expected behaviour of Microsoft Word i.e. when you change the direct formatting of TOC items manually using even Microsoft Word application itself and then “Update entire table”, the formatting is reverted to the original.

To workaround this problem, you need to change the style for each level in the table of contents. These styles are separate from the styles that you applied to the headings in your document. After you make the changes you want to the TOC style(s), Microsoft Word uses that TOC style(s) each time it updates the table of contents. For example, please try specifying the formatting via TOC styles as follows:

Style toc1 = doc.Styles[StyleIdentifier.Toc1];
toc1.Font.Color = Color.Red;
toc1.Font.Bold = true;
toc1.Font.Size = 10;
toc1.Font.Name = "Times New Roman";
toc1.ParagraphFormat.SpaceAfter = 0;
toc1.ParagraphFormat.SpaceBefore = 0;

Komal:

Also, I want to read one of the Tracking ID(53951-1370344009) present in the footer of the document. Please find the attached AA_Input.doc. I tried to read it using the below code. but, it is giving the some other value with-in the footer itself. Could you plase help me to fetch this green text.

Your target text is located inside a Cell and you can try run the following code to print that specific Paragraph’s text:

Document doc = new Document(@"C:\Temp\AA_Output.doc");
foreach (Section section in doc.Sections)
{
    HeaderFooter pf = section.HeadersFooters[HeaderFooterType.FooterPrimary];
    Console.WriteLine(pf.Tables[0].LastRow.LastCell.FirstParagraph.ToString(SaveFormat.Text));
}

I hope, this helps.

Best regards,

Hi Awais Hafeez,

Thank you so much for your feedback and code sniffet. I am able to resolve all the known issues.

Hi Komal,

Thanks for your feedback. Please let us know any time you have any further queries. We are always glad to help you.

Best regards,

Hi Komal,

Regarding WORDSNET-8413, our development team has completed the work on this and has come to a conclusion that this issue and the undesired behaviour you’re observing in Aspose.Words is actually not a bug. So, we have closed this issue as ‘Not a Bug’. Please see the workaround code here.

Best regards,

Hi, Awais Hafeez,

While working with custom styling for another document I run in to issues while applying the styles.

The requirement is slight complicated in this case where we need to apply more than one style to different texts in the same paragraph texts in predefined order. So, I tried to copy the paragraph runs, that are in between the start and end tag and then try to apply the styling for each run. but its throwing me exception. Please help me in resolving this issue.

Given below is the code for sample input file and hardcoded styling name and order etc for your understanding and analyze the issue. Please let me know, how can we apply two different styles to part of the text in paragraph in sequence.

//1. Load an existing Word document in memory
Document _pAsposeDocument = new Document("C:\\EEComInput.rtf");
//2.set the full file path of the customStyles file related to the document
_pAsposeDocument.AttachedTemplate = "C:\\EECom_Style.dotx";
//3.import custom styles from .DOTX document into the BIP document 
Document CustomStylesDoc = new Document(_pAsposeDocument.AttachedTemplate);
foreach (Style srcStyle in CustomStylesDoc.Styles)
{
    if (!srcStyle.BuiltIn)
        _pAsposeDocument.Styles.AddCopy(srcStyle);
}
//3. get the list of custom styles that needs to serached and applied in the document
List<string> customStylesNames = new List<string>();
customStylesNames.Add("Style36-Headings");
customStylesNames.Add("Style38-Heavy 11");
customStylesNames.Add("Style58-One and half Spacing");
customStylesNames.Add("Style66-Single Space");
customStylesNames.Add("Style70-Summary");
//5. Apply custom Styles to texts that exists between special Start and End tags.
NodeCollection paragraphs = _pAsposeDocument.GetChildNodes(NodeType.Paragraph, true);
foreach (String custStyleName in customStylesNames)
{
    //Construct the start and end tag.
    String StartTagName = "Start-" + custStyleName;
    String EndTagName = "End-" + custStyleName;
    //Get the actual customStyle name.
    //remove the "Style*-" from the customStyleName. 
    int firstDashIndex = custStyleName.IndexOf('-');
    String StyleName = custStyleName.Substring(firstDashIndex + 1);
    foreach (Paragraph para in paragraphs)
    {
        para.ParagraphFormat.ClearFormatting();
        List<Run> lstParaRuns = new List<Run>();
        bool isCustText = false;
        foreach (Run run in para.Runs)
        {
            //Remove the Start and End Tags if present.
            if (run.Text.Contains(StartTagName))
            {
                isCustText = true;
                run.Text = run.Text.Replace(StartTagName, "");
            }
            if (run.Text.Contains(EndTagName))
            {
                lstParaRuns.Add(run); //both start and end tag present in the same run..so add it here and set isCustText to false.
                isCustText = false;
                run.Text = run.Text.Replace(EndTagName, "");
            }
            if (isCustText) //Keep adding the run to list until we find the EndTagName..
            {
                lstParaRuns.Add(run);
            }
        }
        foreach (Run run in lstParaRuns)
        {
            //Apply the custom style that was imported from the template
            run.Font.Style = _pAsposeDocument.Styles[StyleName]; // This is throughing excepiton.
            //run.Font.Style.Name = _pAsposeDocument.Styles[StyleName].Name; -> This line not throwing exception. But it is not adding any style. When I click on this text and then check the style in MSWORD styles window, no style is highlighted/applied.
        }
        //if( isCustomText == true)
        //para.ParagraphFormat.Style = _pAsposeDocument.Styles[custStyleName];// this is old code for applying single style to entire paragraph.
    }
}
//6. Save the modified document.
_pAsposeDocument.Save("C:\\EEComOutput.doc");

The input .rtf file and styling template .dotx file are attached in EEComInput_latest.zip.

Hi Komal,

Thanks for your inquiry.

Please note that formatting is applied on a few different levels. For example, let’s consider formatting of simple text. Text in documents is represented by Run element and a Run can only be a child of a Paragraph. You can apply formatting 1) to Run nodes by using Character Styles e.g. a Glyph Style, 2) to the parent of those Run nodes i.e. a Paragraph node (possibly via paragraph Styles) and 3) you can also apply direct formatting to Run nodes by using Run attributes (Font). In this case the Run will inherit formatting of Paragraph Style, a Glyph Style and then direct formatting.

Actually, there are few types of styles – Paragraph styles, Character styles, List styles and Table styles. In your case, the exception occurs because you’re trying to specify formatting to a Run node using a Paragraph style. To overcome this problem, please try applying a Character Style to Run nodes.

Best regards,

Hi Awais Hafeez,

Thanks for the information on various styles.
In our .dotx style template also we have various style types. ie, Paragraph styles, char styles, table styles etc.

For eg: In my input document, with-in a paragraph I have to apply two styles. first paragraph style and then char style for the selected words with-in a paragrapah. All the words/paragraphs in my input .rtf file has the embedded Start and End tags. I need to apply the corresponding style to the Texts that exits between these START And END tags.

I have been following the below approach.
a. I have grouped all the existing styles into two types. 1. Paragraph styles 2. Char Styles.
NOTE: Based on your suggestion, I am open to change this grouping… if required we can have more than two groupings also… and also move the styles to different groupings.

b. I am appplying all the paragraph styles first, and then followed by the char styles.

But, I have been seeing many issues.

  1. Char styles are being applied correctly. But the paragraph styles are not applying correctly.

  2. Aspose is generating extra space before and after the paragraph.
    The styles related to spacing are also not applied eg: One and half Spacing , Single Space, Half Like spacing.

  3. The bullets related styles have the paragraph property, but none of them are getting applied.

  4. Paragraph rows with-in the table are also not applied. eg: Key Date Style

The console application along with following files are attached (Tester_EECom.zip). all the files are present in the application root directory.
NOTE: Please copy the Aspose.Words.dll and Aspose.Words.lic files to application root directory to build and run the code.

  1. EEComInput.rtf - input file
  2. EECom_Style.dotx - style template
  3. EEComOutput_AsposeGenerated.doc - is the ouput generated by Aspose with all the issues highlighted with comments.
  4. EEComOutput_Expected.doc - Expected output styling. You can compare this doc with the EEComOutput_AsposeGenerated.doc to see the differences and understand/analyze the issues.

Please let me know what is the good way to apply these styles. We want aspose to generate the output similr to EEComOutput_Expected.doc.

Hi Komal,

Thanks for your inquiry. We’re checking with this scenario and will get back to you soon.

Best regards,

Thanks Awais Hafeez,

We are awaiting for your response.