Aspose.words for .NET - selectability of lists in word document output

Hello,

We are using aspose.words in our web application to output a bunch of multiple choice questions to a word document.

Our aim is to produce a numbered list in the word document with each question being a single entry. The set of answers to a multiple choice question is a sub-list numbered alphabetically. The client should be able to click on a single question number or answer letter and have all of the question numbers/answer letters selected, in order for them to easily adjust formatting for all of the question numbers/answer letters in the document.

To acheive this, we are using the builder.InsertHtml() method to insert the questions and answers to each question into the document as HTML ordered lists. A snippet of example HTML is shown below:

<ol>
       <li>Question One</li>
              <ol type="a">
                   <li>Answer One</li>
                   <li>Answer Two</li>
                   <li>Answer Three</li>
             </ol>
      </li>
      <li>Question Two</li>

              <ol type="a">

                   <li>Answer One</li>

                   <li>Answer Two</li>

                   <li>Answer Three</li>

             </ol>

      </li>
</ol>

When the document is produced, the HTML ordered lists render as Word numbered/lettered lists, as desired. We are able to click on any question number and all of the question numbers in the document are selected. However, when we click on a answer letter, only the answer letters for that particular question are selected, not all of the answer letters in the document.

When we ouput the raw HTML and then open the HTML document via Microsoft Word, clicking on one answer letter selects all of the answer letters in the document - the desired behaviour.

The attached sample document shows the output we are trying to acheive, with the desired behaviour when an answer letter is clicked.

Your help in acheiving this desired behaviour is much appreciated.

Regards,

Michael

Hi

Thanks for your request. This occurs because items belong to different lists:

<ol>
    <li>Question One</li>
    <ol type="a">
        <li>Answer One</li>
        <li>Answer Two</li>
        <li>Answer Three</li>
    </ol>
    </li>
    <li>Question Two</li>
    <ol type="a">
        <li>Answer One</li>
        <li>Answer Two</li>
        <li>Answer Three</li>
    </ol>
    </li>
</ol>

Maybe in your case, you can build lists programmatically. Please see the following code for example:

Document doc = new Document();
// Create a list based on one of the Microsoft Word list templates.
List list = doc.Lists.Add(ListTemplate.NumberDefault);
// Completely customize one list level.
ListLevel level1 = list.ListLevels[0];
level1.NumberStyle = NumberStyle.Arabic;
level1.NumberFormat = "\x0000";
// Completely customize yet another list level.
ListLevel level2 = list.ListLevels[1];
level2.NumberStyle = NumberStyle.LowercaseLetter;
level2.NumberFormat = "\x0001";
level2.RestartAfterLevel = 0;
// Now add some text that uses the list that we created.
// It does not matter when to customize the list - before or after adding the paragraphs.
DocumentBuilder builder = new DocumentBuilder(doc);
builder.ListFormat.List = list;
builder.Writeln("Question One");
builder.ListFormat.ListIndent();
builder.Writeln("Answer One");
builder.Writeln("Answer Two");
builder.Writeln("Answer Three");
builder.ListFormat.ListOutdent();
builder.Writeln("Question Two");
builder.ListFormat.ListIndent();
builder.Writeln("Answer One");
builder.Writeln("Answer Two");
builder.Writeln("Answer Three");
builder.ListFormat.RemoveNumbers();
// Save ouput document.
doc.Save(@"Test001\out.doc");

Hope this helps.
Best regards.

Hi Alexey,

Thanks for your reply.

Using the lists you suggested seems to be the way to go. However, I have some queries related to its use.

The questions we wish to insert into the document often have multiple “bits” of content, within which line breaks need to be inserted. We only wish to output the list number once, on the first line of the question content:

1.  <Question content>
     <More question content>

     <Even more question content>

      a. <First answer>
      b. <Second answer>
      c. <Third answer>

     <Even more question content>

2. <Question content>

     <More question content>
      etc...

The same applies to the answers.
The content of both the questions and answers is HTML content.
How then, do we specify programmatically that a list entry begin at a certain point, place (html) content “within” that list entry, and then end that list entry? I imagine the psuedocode would be something like the following:

builder.InsertHtml(QuestionContent);
builder.InsertBreak(BreakType.LineBreak);
builder.InsertHtml(MoreQuestionContent);

builder.ListFormat.ListIndent();

builder.InsertHtml(AnswerOne);

builder.InsertHtml(AnswerTwo);

builder.ListFormat.ListOutdent();

Regards,

Michael

Hi

Thanks for your request. IF your HTML string is something like the following:

string html = "Question content<br />More question content<br />Even more question content";
 
Then your code will look like the following:
 
Document doc = new Document();
 
// Create a list based on one of the Microsoft Word list templates.
List list = doc.Lists.Add(ListTemplate.NumberDefault);
 
// Completely customize one list level.
ListLevel level1 = list.ListLevels[0];
level1.NumberStyle = NumberStyle.Arabic;
level1.NumberFormat = "\x0000";
 
// Completely customize yet another list level.
ListLevel level2 = list.ListLevels[1];
level2.NumberStyle = NumberStyle.LowercaseLetter;
level2.NumberFormat = "\x0001";
level2.RestartAfterLevel = 0;
 
// Now add some text that uses the list that we created.            
// It does not matter when to customize the list - before or after adding the paragraphs.
DocumentBuilder builder = new DocumentBuilder(doc);
 
builder.ListFormat.List = list;
builder.InsertHtml("Question content<br />More question content<br />Even more question content");
builder.Writeln();
 
builder.ListFormat.ListIndent();
builder.InsertHtml("Answer One<br />More answer content");
builder.Writeln();
builder.InsertHtml("Answer Two<br />More answer content");
builder.Writeln();
builder.InsertHtml("Answer Three<br />More answer content");
builder.Writeln();
 
builder.ListFormat.ListOutdent();
builder.InsertHtml("Question content<br />More question content<br />Even more question content");
builder.Writeln();
 
builder.ListFormat.ListIndent();
builder.InsertHtml("Answer One<br />More answer content");
builder.Writeln();
builder.InsertHtml("Answer Two<br />More answer content");
builder.Writeln();
builder.InsertHtml("Answer Three<br />More answer content");
builder.Writeln();
 
builder.ListFormat.RemoveNumbers();
 
// Save ouput document.
doc.Save(@"Test001\out.doc");

Hope this helps.

Best regards.

Alexey,

Thanks for your reply. I have implemented the approach you suggsted and the lists appear as desired. I have a couple of additional queries:

  1. We have observed that, when using builder.InsertHtml(HTML) with the above code for numbered lists, if the HTML contains an


    (horizontal line) element, then the numbered list stops at that question and does not reappear for subsequent questions. This appears to be a bug in version 6.0.0. Has this been corrected in a subsequent version?
  2. On occasion we require outputting two language versions for a list of questions. The desired output would be either:

1. <1st language Question 1 content>
    <More 1st language Question 1 content>
        a. <1st language Answer a>
        b. <1st language Answer b>
        c. <1st language Answer c>

   <2nd language Question 1 content>
   <More 2nd language Question 1 content>
       a. <2nd language Answer a>
       b. <2nd language Answer b>
       c. <1st language Answer c>

2. <1st language Question 2 content>
    <More 1st language Question 2 content>

        a. <1st language Answer a>

        b. <1st language Answer b>

        c. <1st language Answer c>



   <2nd language Question 2 content>
   <More 2nd language Question 2 content>

       a. <2nd language Answer a>

       b. <2nd language Answer b>

       c. <1st language Answer c>

Or:

1. <1st language Question 1 content>
     <More 1st language Question 1 content>

        a. <1st language Answer a>

        b. <1st language Answer b>

        c. <1st language Answer c>



1.   <2nd language Question 1 content>
      <More 2nd language Question 1 content>

       a. <2nd language Answer a>

       b. <2nd language Answer b>

       c. <1st language Answer c>



2. <1st language Question 2 content>
    <More 1st language Question 2 content>


        a. <1st language Answer a>


        b. <1st language Answer b>


        c. <1st language Answer c>





2.   <2nd language Question 2 content>
      <More 2nd language Question 2 content>


       a. <2nd language Answer a>


       b. <2nd language Answer b>


       c. <1st language Answer c>

In either case, we require both the outer and inner lists to be entirely selected when one element in the list is selected.
In the first case, we require the 2nd language question content to be indented by the same amount as the 1st language question content. In the second case, we require the numbered list to advance numbers only every second list item

I have tried to implement either approach without success. Can you advise if this is possible in v6.0.0 or later, and how this might be done?

Thanks in advance for your help.

Michael

Hi Michael,

Thanks for your request.

  1. No, this is not a bug.
    is imported to MS Word document as Horizontal Rule, which is a shape in an empty paragraph. So
    is imported as a separate paragraph with Horizontal Rule shape.
    When you use InsertHtml, paragraph formatting is taken from HTML, so list formatting is reset.

  2. Do you really need to use HTML? It will much simpler to achieve what you need without HTML. Please let me know.

Best regards.

Hi Alexey,

Thanks again for your reply. In regards to both issues:

  1. Fair enough - we always require the list formatting to be preserved across the whole document, so we remove <hr /> and <p> tags from the html that is passed to builder.InsertHtml(). Could you please tell us if there are any other html tags that, when imported to MS word, reset the list formatting? We have not come across any as yet.

  2. You don’t need to worry about this - we have acheived a satisfactory result by having the second language questions & answers in two additional (separate) MS word numbered lists.

Regards,

Michael

Hi Michael,

It is perfect that you resolved the problem. You should also remove DIV, LI, OL, UL, H1…H6 tags from your HTML string.
Best regards.