Table layout when cells merged and widths set

We have a generic table builder that can inject tables into a word document at a specific Word field. I’ve simplified the code to reproduce problem and the document. Could you please tell me two things:

  1. Why don’t the widths/layout of the cells all line up when the sum of the column widths for each of the rows are the same?

  2. When I have Word set to display all formatting marks, what are the end marks at the end of each table row? I only seem to get those when I have a document template as the source (as in my sample code attached). But if I don’t open a sample document and just create an empty document then a documentBuilder from that, I don’t seem to get those (and the problem doesn’t seem to present itself).

Thanks so much,

Terry

Here is code to generate document:

public void TestTableBuilder()
{
    var fileName = @"c:\users\terry.aney\desktop\Aspose.Testing\TableBuilder.doc";
    Document document;
    using (var ms = new MemoryStream(File.ReadAllBytes(@"c:\users\terry.aney\desktop\Aspose.Testing\TableBuilder.docx")))
    {
        document = new Document(ms);
    }
    var documentBuilder = new DocumentBuilder(document);
    var table = documentBuilder.StartTable();
    var field = document.Sections[0].Body.Range.Fields[0];
    documentBuilder.MoveToField(field, false);
    field.Result = ""; //can’t delete field name or the foreach doesn’t work
    // Merge four cells
    FormatCell(documentBuilder, 620, CellMerge.First, "Basic Information");
    SpanColumns(documentBuilder, 4);
    documentBuilder.EndRow();
    // No Merge
    FormatCell(documentBuilder, 260, CellMerge.None, "1");
    FormatCell(documentBuilder, 150, CellMerge.None, "2");
    FormatCell(documentBuilder, 20, CellMerge.None, "3");
    FormatCell(documentBuilder, 190, CellMerge.None, "4");
    documentBuilder.EndRow();
    // Merge four cells
    FormatCell(documentBuilder, 620, CellMerge.First, "at Benefit Commencement Date");
    SpanColumns(documentBuilder, 4);
    documentBuilder.EndRow();
    // Merge two cells
    FormatCell(documentBuilder, 260, CellMerge.First, "");
    SpanColumns(documentBuilder, 1);
    FormatCell(documentBuilder, 360, CellMerge.First, "at Benefit Commencement Date");
    SpanColumns(documentBuilder, 3);
    documentBuilder.EndRow();
    // No Merge
    FormatCell(documentBuilder, 260, CellMerge.None, "1");
    FormatCell(documentBuilder, 150, CellMerge.None, "2");
    FormatCell(documentBuilder, 20, CellMerge.None, "3");
    FormatCell(documentBuilder, 190, CellMerge.None, "4");
    documentBuilder.EndRow();
    table.AllowAutoFit = false;
    table.PreferredWidth = PreferredWidth.Auto;
    table.LeftIndent = ConvertUtil.InchToPoint(0.1);
    table.ClearBorders();
    documentBuilder.EndTable();
    document.Save(fileName);
}

public void SpanColumns(DocumentBuilder documentBuilder, int columnCount)
{
    for (int i = 0; i
    {
        documentBuilder.InsertCell();
        documentBuilder.CellFormat.HorizontalMerge = CellMerge.Previous;
    }
}

public void FormatCell(DocumentBuilder documentBuilder, double width, CellMerge merge, string value)
{
    documentBuilder.RowFormat.AllowBreakAcrossPages = false;
    documentBuilder.RowFormat.HeadingFormat = false;
    documentBuilder.InsertCell();
    documentBuilder.CellFormat.HorizontalMerge = merge;
    documentBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Right;
    documentBuilder.CellFormat.PreferredWidth = PreferredWidth.FromPoints(ConvertUtil.InchToPoint(width / 96));
    documentBuilder.CellFormat.TopPadding = documentBuilder.CellFormat.BottomPadding = ConvertUtil.InchToPoint(0.02);
    documentBuilder.CellFormat.LeftPadding = documentBuilder.CellFormat.RightPadding = ConvertUtil.InchToPoint(0.1);
    documentBuilder.Write(value);
}

Hi Terry,

Thanks for your inquiry. Please use the value of AllowAutoFit as true in your code example. The default value of this property is true. Please remove the following line of code from your application to get the required output.

table.AllowAutoFit = false;

We have attached the output document with this post for your kind reference. Please let us know if you have any more queries.

Hmm…that seems counter intuitive. If I specifically want to control widths of table columns, why would I set this to true and allow Word to resize columns to ‘fit the contents’?

Hi Terry,

Thanks for your inquiry. The Table.AllowAutoFit property enables cells in the table to grow and shrink to accommodate their contents. This property can be used in conjunction with a preferred cell width to format a cell which auto fits its content but which also has an initial width.

We suggest you please read about specifying table and cell widths from here:
https://docs.aspose.com/words/net/applying-formatting/

So I read it. Not entirely clear given how the code behaves and your original suggestion.

That link you gave says “If the table has Table.AllowAutoFit enabled then any change in CellFormat.Width value is ignored and the cell is fitted to its contents instead.” This isn’t really what I want.

If I want to precisely set the widths of cells and allow that to control the overall width, what do I do? I’m was guessing:

a) Set table.AllowAutoFit = false
b) Set table.PreferredWidth = Auto
c) Set cell.PreferredWidth = PreferredWidth.FromPoints(…)

But you are saying that is wrong. I’ve read your article a couple times and still feel like that is way to go when desiring to set widths on cells and let table calculate/fit that width.

Could you please tell me the correct/suggested way to accomplish what I desire?

Hi Terry,

Thanks for your inquiry. Table.AllowAutoFit = false generates incorrect output. For the sake of correction, we have logged this problem in
our issue tracking system as WORDSNET-12598. You will be notified via this
forum thread once this issue is resolved.

We apologize for your inconvenience.

Hi Terry,

Thanks for your patience. Please try following code snippet for row #1 and #3.

FormatCell(documentBuilder, 620, CellMerge.First, "at Benefit Commencement Date");
// Add 3 cell instead of 4 to get total cols for this row equal to 4.
SpanColumns(documentBuilder, 3);
documentBuilder.EndRow();

And try following code snippet for row #4.

FormatCell(documentBuilder, 260, CellMerge.First, "");
// First cell should probably spans 1 col, so do not add more cells to first cell
// SpanColumns(documentBuilder, 1);
// and second cell should probably spans 3 col to get total cols for this row equal to 4 as well.
FormatCell(documentBuilder, 360, CellMerge.First, "at Benefit Commencement Date");
// add 2 cell instead of 3
SpanColumns(documentBuilder, 2);
documentBuilder.EndRow();

Hope this helps you. If you still face problem, please manually create your expected Word document using Microsoft Word for your scenario and attach it here for further analysis.