Unable to Retrieve Table Preset Styles (Such As Color, Background Color, Font, etc.) Applied in PowerPoint When Using Aspose.Slides for .NET

Hello,
I’m unable to retrieve the preset styles of tables created in PowerPoint when using Aspose.Slides for .NET. I’m reading these tables and generating their HTML representations.

I’m using version 24.3.0.0 of the Aspose.Slides for .NET DLL.

Code snippets:

try
{
	using (var pres = new Presentation(@"C:\\Users\\abc\\Desktop\\Tables.pptx"))
	{
		var slide = pres.Slides[5]; // For example used last slide

		foreach (var shape in slide.Shapes)
		{
			if (shape is ITable table)
			{
				string html = ExportTableToHtml(table);
				Console.WriteLine(html); // Or save it to a file
			}
		}
	}

	return true;
}
catch (Exception ex)
{
	return false;
}

public static string ExportTableToHtml(ITable table)
{
	var html = new StringBuilder();
	try
	{
		//html.Append("<table border='1' cellspacing='0' cellpadding='0' style='border-collapse:collapse;'>");
		html.Append("<table style=\"border-collapse: collapse; width:100%\">");

		int rows = table.Rows.Count;
		int cols = table.Columns.Count;

		// Track merged cells
		var skipCells = new bool[rows, cols];

		for (int i = 0; i < rows; i++)
		{
			var row = table.Rows[i];
			float rowHeight = (float)row.MinimalHeight;

			html.Append("<tr");
			if (rowHeight > 0)
				html.Append($" style='height:{rowHeight}px;'");
			html.Append(">");

			for (int j = 0; j < cols; j++)
			{
				if (skipCells[i, j])
					continue;

				// Safety check to avoid index out of range
				if (j >= table.Rows[i].Count)
					continue;

				var cell = table.Rows[i][j];
				var text = cell?.TextFrame?.Text ?? "";
				var style = new StringBuilder();

				// Column width
				float colWidth = (float)table.Columns[j].Width;
				if (colWidth > 0)
					style.Append($"width:{colWidth}px;");

				// Fill color
				var fill = cell?.CellFormat?.FillFormat;
				if (fill?.FillType == Aspose.Slides.FillType.Solid)
				{
					var bg = fill.SolidFillColor?.Color;
					if (bg != null)
					{
						string hexColor = $"#{bg.Value.R:X2}{bg.Value.G:X2}{bg.Value.B:X2}";
						style.Append($"background-color:{hexColor};");
						//style.Append($"background-color:#{bg.Value.ToArgb() & 0xFFFFFF:X6};");
					}
				}

				// Font and text formatting (first portion)
				var portion = cell?.TextFrame?.Paragraphs?[0]?.Portions?[0];
				if (portion != null)
				{
					var pf = portion.PortionFormat;

					if (pf?.FillFormat?.FillType == Aspose.Slides.FillType.Solid)
					{
						var color = pf.FillFormat.SolidFillColor?.Color;
						if (color != null)
							style.Append($"color:#{color.Value.ToArgb() & 0xFFFFFF:X6};");
					}

					if (!float.IsNaN(pf.FontHeight) && pf.FontHeight > 0)
						style.Append($"font-size:{pf.FontHeight}px;");

					if (pf.LatinFont != null)
						style.Append($"font-family:'{pf.LatinFont.FontName}';");

					if (pf.FontBold == NullableBool.True)
						style.Append("font-weight:bold;");

					if (pf.FontItalic == NullableBool.True)
						style.Append("font-style:italic;");

					if (pf.FontUnderline != TextUnderlineType.NotDefined)
						style.Append("text-decoration:underline;");

					if (pf.StrikethroughType != TextStrikethroughType.NotDefined)
						style.Append("text-decoration:line-through;");
				}

				// Text alignment
				var para = cell?.TextFrame?.Paragraphs?[0];
				if (para != null)
				{
					var align = para.ParagraphFormat.Alignment;
					if (align != TextAlignment.Left && align != TextAlignment.NotDefined)
						style.Append($"text-align:{align.ToString().ToLowerInvariant()};");
				}

				// Vertical alignment
				var valign = cell?.TextAnchorType;
				if (valign != null && valign != TextAnchorType.Top)
					style.Append($"vertical-align:{valign.ToString().ToLowerInvariant()};");

				// Cell padding from TextFrame margins
				if (cell.TextFrame != null && cell.TextFrame.TextFrameFormat != null)
				{
					var format = cell.TextFrame.TextFrameFormat;
					double marginTop = double.IsNaN(format.MarginTop) ? 0 : format.MarginTop;
					double marginBottom = double.IsNaN(format.MarginBottom) ? 0 : format.MarginBottom;
					double marginLeft = double.IsNaN(format.MarginLeft) ? 0 : format.MarginLeft;
					double marginRight = double.IsNaN(format.MarginRight) ? 0 : format.MarginRight;
					style.Append($"padding:{marginTop}px {marginRight}px {marginBottom}px {marginLeft}px;");
				}

				// Border styling
				foreach (var (border, name) in new[] {
		(cell.CellFormat?.BorderTop, "top"),
		(cell.CellFormat?.BorderBottom, "bottom"),
		(cell.CellFormat?.BorderLeft, "left"),
		(cell.CellFormat?.BorderRight, "right")
	})
				{
					if (border?.FillFormat?.FillType == Aspose.Slides.FillType.Solid)
					{
						var color = border.FillFormat.SolidFillColor?.Color;
						if (color != null)
							style.Append($"border-{name}:1px solid #{color.Value.ToArgb() & 0xFFFFFF:X6};");
					}
					else
					{
						style.Append($"border-{name}:1px solid #000;");
					}
				}

				// Rowspan and Colspan
				int rowspan = cell.RowSpan;
				int colspan = cell.ColSpan;

				for (int r = i; r < i + rowspan && r < rows; r++)
				{
					// Make sure row exists and column index is valid
					if (r >= table.Rows.Count)
						continue;

					for (int c = j; c < j + colspan && c < cols; c++)
					{
						if (c >= table.Rows[r].Count)
							continue;

						if (!(r == i && c == j))
							skipCells[r, c] = true;
					}
				}

				var td = new StringBuilder("<td");
				if (rowspan > 1)
					td.Append($" rowspan='{rowspan}'");
				if (colspan > 1)
					td.Append($" colspan='{colspan}'");

				if (style.Length > 0)
					td.Append($" style='{style}'");

				td.Append($">{System.Net.WebUtility.HtmlEncode(text)}</td>");
				html.Append(td.ToString());
			}

			html.Append("</tr>");
		}

		html.Append("</table>");
	}
	catch (Exception ex)
	{

	}
	return html.ToString();
}

Attachments:
PPT.zip (3.3 MB)

@RajChauhan,
Thank you for contacting free support. I need some time to check the issue. I will get back to you as soon as possible.

@andrey.potapov,
Thanks for the update. Awaiting your follow-up.

@RajChauhan,
Thank you for your patience. Please note that many formatting options for PowerPoint objects (text, tables, etc.) may be set indirectly. In such cases, they are returned as NotDefined, null, or NaN, but the actual styles are inherited from parent objects or the presentation theme. To retrieve the final style values applied to these objects, use the GetEffective method of the format interfaces.

The updated ExportTableToHtml method:

public static string ExportTableToHtml(ITable table)
{
    var html = new StringBuilder();
    try
    {
        //html.Append("<table border='1' cellspacing='0' cellpadding='0' style='border-collapse:collapse;'>");
        html.Append("<table style=\"border-collapse: collapse; width:100%\">");

        int rows = table.Rows.Count;
        int cols = table.Columns.Count;

        // Track merged cells
        var skipCells = new bool[rows, cols];

        for (int i = 0; i < rows; i++)
        {
            var row = table.Rows[i];
            float rowHeight = (float)row.MinimalHeight;

            html.Append("<tr");
            if (rowHeight > 0)
                html.Append($" style='height:{rowHeight}px;'");
            html.Append(">");

            for (int j = 0; j < cols; j++)
            {
                if (skipCells[i, j])
                    continue;

                // Safety check to avoid index out of range
                if (j >= table.Rows[i].Count)
                    continue;

                var cell = table.Rows[i][j];
                var text = cell?.TextFrame?.Text ?? "";
                var style = new StringBuilder();

                // Column width
                float colWidth = (float)table.Columns[j].Width;
                if (colWidth > 0)
                    style.Append($"width:{colWidth}px;");

                // Fill color
                var fill = cell?.CellFormat?.GetEffective().FillFormat;
                if (fill?.FillType == Aspose.Slides.FillType.Solid)
                {
                    var bg = fill.SolidFillColor;
                    if (bg != null)
                    {
                        string hexColor = $"#{bg.R:X2}{bg.G:X2}{bg.B:X2}";
                        style.Append($"background-color:{hexColor};");
                        //style.Append($"background-color:#{bg.Value.ToArgb() & 0xFFFFFF:X6};");
                    }
                }

                // Font and text formatting (first portion)
                var portion = cell?.TextFrame?.Paragraphs?[0]?.Portions?[0];
                if (portion != null)
                {
                    var pf = portion.PortionFormat.GetEffective();

                    if (pf?.FillFormat?.FillType == Aspose.Slides.FillType.Solid)
                    {
                        var color = pf.FillFormat.SolidFillColor;
                        if (color != null)
                            style.Append($"color:#{color.ToArgb() & 0xFFFFFF:X6};");
                    }

                    if (!float.IsNaN(pf.FontHeight) && pf.FontHeight > 0)
                        style.Append($"font-size:{pf.FontHeight}px;");

                    if (pf.LatinFont != null)
                        style.Append($"font-family:'{pf.LatinFont.FontName}';");

                    if (pf.FontBold == true)
                        style.Append("font-weight:bold;");

                    if (pf.FontItalic == true)
                        style.Append("font-style:italic;");

                    if (pf.FontUnderline != TextUnderlineType.NotDefined)
                        style.Append("text-decoration:underline;");

                    if (pf.StrikethroughType != TextStrikethroughType.NotDefined)
                        style.Append("text-decoration:line-through;");
                }

                // Text alignment
                var para = cell?.TextFrame?.Paragraphs?[0];
                if (para != null)
                {
                    var align = para.ParagraphFormat.GetEffective().Alignment;
                    if (align != TextAlignment.Left && align != TextAlignment.NotDefined)
                        style.Append($"text-align:{align.ToString().ToLowerInvariant()};");
                }

                // Vertical alignment
                var valign = cell?.TextAnchorType;
                if (valign != null && valign != TextAnchorType.Top)
                    style.Append($"vertical-align:{valign.ToString().ToLowerInvariant()};");

                // Cell padding from TextFrame margins
                if (cell.TextFrame != null && cell.TextFrame.TextFrameFormat.GetEffective() != null)
                {
                    var format = cell.TextFrame.TextFrameFormat.GetEffective();
                    double marginTop = double.IsNaN(format.MarginTop) ? 0 : format.MarginTop;
                    double marginBottom = double.IsNaN(format.MarginBottom) ? 0 : format.MarginBottom;
                    double marginLeft = double.IsNaN(format.MarginLeft) ? 0 : format.MarginLeft;
                    double marginRight = double.IsNaN(format.MarginRight) ? 0 : format.MarginRight;
                    style.Append($"padding:{marginTop}px {marginRight}px {marginBottom}px {marginLeft}px;");
                }

                // Border styling
                foreach (var (border, name) in new[] {
                    (cell.CellFormat?.GetEffective().BorderTop, "top"),
                    (cell.CellFormat?.GetEffective().BorderBottom, "bottom"),
                    (cell.CellFormat?.GetEffective().BorderLeft, "left"),
                    (cell.CellFormat?.GetEffective().BorderRight, "right")
                })
                {
                    if (border?.FillFormat?.FillType == Aspose.Slides.FillType.Solid)
                    {
                        var color = border.FillFormat.SolidFillColor;
                        if (color != null)
                            style.Append($"border-{name}:1px solid #{color.ToArgb() & 0xFFFFFF:X6};");
                    }
                    else
                    {
                        style.Append($"border-{name}:1px solid #000;");
                    }
                }

                // Rowspan and Colspan
                int rowspan = cell.RowSpan;
                int colspan = cell.ColSpan;

                for (int r = i; r < i + rowspan && r < rows; r++)
                {
                    // Make sure row exists and column index is valid
                    if (r >= table.Rows.Count)
                        continue;

                    for (int c = j; c < j + colspan && c < cols; c++)
                    {
                        if (c >= table.Rows[r].Count)
                            continue;

                        if (!(r == i && c == j))
                            skipCells[r, c] = true;
                    }
                }

                var td = new StringBuilder("<td");
                if (rowspan > 1)
                    td.Append($" rowspan='{rowspan}'");
                if (colspan > 1)
                    td.Append($" colspan='{colspan}'");

                if (style.Length > 0)
                    td.Append($" style='{style}'");

                td.Append($">{System.Net.WebUtility.HtmlEncode(text)}</td>");
                html.Append(td.ToString());
            }

            html.Append("</tr>");
        }

        html.Append("</table>");
    }
    catch (Exception ex)
    {

    }
    return html.ToString();
}

More examples:
Shape Effective Properties|Aspose.Slides Documentation

1 Like

@andrey.potapov Thank you for the solution. I’m now able to retrieve the background color, but when comparing the source table with the output table, I notice issues with borders, margin, padding, and spacing.

Refer to the screenshot below:
image.png (54.0 KB)

The table on the left is from my PowerPoint source, and the one on the right is the generated HTML table.

@RajChauhan,
Thank you for the note.

We have opened the following new ticket(s) in our internal issue tracking system and will investigate the case according to the terms mentioned in Free Support Policies.

Issue ID(s): SLIDESNET-44978

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.