Aspose.Words.Tables.Table doesn't handle horizontally-merged cells correctly

Take a look at the attached table.docx.
It seems like Aspose.Words is supposed to give you one cell for every possible position in the grid. The top position of a merged cell will be marked “First” for VerticalMerge. The left position of a merged cell will be marked “First” for HorizontalMerge. All other positions in the merged cell will be marked as “Previous”. So in my test table from table.docx it should be (as pairs of (Horizontal, Vertical) where F=First, P=Previous, N=None):

(F, F) (P, F) (N, N) (N, F)
(F, P) (P, P) (N, N) (N, P)
(N, N) (F, N) (P, N) (N, N)
(N, N) (N, N) (N, N) (N, N)

but instead Aspose.Words gives me

(N, F) (N, N) (N, F)
(N, P) (N, N) (N, P)
(N, N) (N, N) (N, N)
(N, N) (N, N) (N, N) (N, N)

So basically, take out all the cells that have Horizontal=Previous and change all the Horizontal=First cells to have Horizontal=None.

You can create the above output with:

var doc = new Aspose.Words.Document("table.docx");
var section = doc.ChildNodes[0] as Aspose.Words.Section;
var body = section.ChildNodes[0] as Aspose.Words.Body;
var table = body.ChildNodes[1] as Aspose.Words.Tables.Table;

foreach (Aspose.Words.Tables.Row row in table.Rows)
{
    string line = "";
    foreach (Aspose.Words.Tables.Cell cell in row.Cells)
    {
        line += "(" + cell.CellFormat.HorizontalMerge.ToString()[0] + ", ";
        line += cell.CellFormat.VerticalMerge.ToString()[0] + ") ";
    }
    Console.WriteLine(line);
}

Hi there,

Thanks for your inquiry. We have tested the scenario and noticed the reported issue, so we have logged a ticket WORDSNET-15475 in our issue tracking system for further investigation and rectification. We will keep you updated about the issue resolution progress within this forum thread.

We are sorry for the inconvenience.

Best Regards,

Hi there,

Thanks for your patience. We have further investigated the issue and noticed it is not a bug. Please unzip your DOCX document and check document.xml file. You will see exactly the same cell merge structure as provided by Aspose.Words.

<w:tbl>
	<w:tr w:rsidR="004442E6" w:rsidTr="00FF5C09">
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="4508" w:type="dxa"/>
				<w:gridSpan w:val="2"/>
				<w:vMerge w:val="restart"/>
				<w:tcBorders>
					<w:top w:val="single" w:sz="12" w:space="0" w:color="ED7D31" w:themeColor="accent2"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:vMerge w:val="restart"/>
			</w:tcPr>
		</w:tc>
	</w:tr>
	<w:tr w:rsidR="004442E6" w:rsidTr="00FF5C09">
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="4508" w:type="dxa"/>
				<w:gridSpan w:val="2"/>
				<w:vMerge/>
				<w:tcBorders>
					<w:bottom w:val="single" w:sz="36" w:space="0" w:color="FFD966" w:themeColor="accent4" w:themeTint="99"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:tcBorders>
					<w:bottom w:val="single" w:sz="12" w:space="0" w:color="ED7D31" w:themeColor="accent2"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:vMerge/>
			</w:tcPr>
		</w:tc>
	</w:tr>
	<w:tr w:rsidR="004442E6" w:rsidTr="009D54D2">
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:tcBorders>
					<w:top w:val="single" w:sz="36" w:space="0" w:color="FFD966" w:themeColor="accent4" w:themeTint="99"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="4508" w:type="dxa"/>
				<w:gridSpan w:val="2"/>
				<w:tcBorders>
					<w:bottom w:val="single" w:sz="36" w:space="0" w:color="FFD966" w:themeColor="accent4" w:themeTint="99"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:tcBorders>
					<w:bottom w:val="single" w:sz="12" w:space="0" w:color="ED7D31" w:themeColor="accent2"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
	</w:tr>
	<w:tr w:rsidR="002849B1" w:rsidTr="00441B9C">
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:tcBorders>
					<w:top w:val="single" w:sz="36" w:space="0" w:color="FFD966" w:themeColor="accent4" w:themeTint="99"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:tcBorders>
					<w:bottom w:val="single" w:sz="36" w:space="0" w:color="FFD966" w:themeColor="accent4" w:themeTint="99"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
		<w:tc>
			<w:tcPr>
				<w:tcW w:w="2254" w:type="dxa"/>
				<w:tcBorders>
					<w:top w:val="single" w:sz="12" w:space="0" w:color="ED7D31" w:themeColor="accent2"/>
				</w:tcBorders>
			</w:tcPr>
		</w:tc>
	</w:tr>
</w:tbl>

Please feel free to contact us for any further assistance.

Best Regards,

You pointed out the vertical merge (vMerge) properties. The bug I described above is only with the horizontal merge properties, which are specified in the XML with <w:gridSpan w:val="2"/>. Aspose is not interpreting the horizontal merge properties at all, as per my original description.

Hi there,

Thanks for your feedback. We have shared your concern with your development team for further investigation. We will notify you as soon as some update is available.

Best Regards,

Hi there,

Thanks for your patience. Please not it is expected behavior. We would like to clarify a bit regarding horizontally merged cells. By Microsoft Word design, rows in a table in a Microsoft Word document are completely independent. It means each row can have any number of cells of any width. So if you imagine first row with one wide cell and second row with two narrow cells, then looking at this document the cell in the first row will appear horizontally merged. But it is not a merged cell; it is just a single wide cell. Another perfectly valid scenario is when the first row has two cells. First cell has CellMerge.First and second cell has CellMerge.Previous, in this case it is a merged cell. In both cases, the visual appearance in MS Word is exactly the same. Both cases are valid.

Here is simple code, which demonstrates the described things.

// Create empty document and DocumentBuilder object.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Configure DocumentBuilder
builder.CellFormat.Borders.LineStyle = LineStyle.Single;
builder.CellFormat.Borders.Color = Color.Black;
// Build table, with simply wide cells.
// First row will contain simply wide cell and in MS Word it will look like merged.
builder.InsertCell();
builder.CellFormat.Width = 200;
builder.Write("This is simply wide cell");
builder.EndRow();
// Insert the second row
builder.InsertCell();
builder.CellFormat.Width = 100;
builder.InsertCell();
builder.CellFormat.Width = 100;
builder.EndRow();
builder.EndTable();
// Insert few paragraphs between table.
builder.Writeln();
builder.Writeln();
// Build table, with merged cells.
// First row will contain merged cells.
builder.InsertCell();
builder.CellFormat.Width = 100;
builder.CellFormat.HorizontalMerge = CellMerge.First;
builder.Write("This is merged cells");
builder.InsertCell();
builder.CellFormat.Width = 100;
builder.CellFormat.HorizontalMerge = CellMerge.Previous;
builder.EndRow();
// Insert the second row
builder.InsertCell();
builder.CellFormat.Width = 100;
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.InsertCell();
builder.CellFormat.Width = 100;
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.EndRow();
builder.EndTable();
// Save output document
doc.Save(@"Test001\out.doc");

Best regards,