Copy Table cell styles

Dear team,
I’m using Aspose.words c#. And I have a requirement, in which there is a template table in my document which each header columns and body columns are bookmarked separately. Now I need to copy all the font styles, paragraphFormat styles and cellFormat styles of each cell based on the bookmark name, so I can apply this style on the main table cells.

@WJobin

To copy the font styles, paragraph formats, and cell formats from bookmarked cells in a table to another table in your document using Aspose.Words for .NET, you can follow these steps:

  1. Access the Bookmarked Cells: First, you need to access the bookmarks that correspond to the header and body cells of your template table.

  2. Retrieve Styles: For each bookmarked cell, retrieve the font styles, paragraph formats, and cell formats.

  3. Apply Styles to Main Table: Once you have the styles from the bookmarked cells, you can apply them to the corresponding cells in your main table.

Here is a sample code snippet that demonstrates how to achieve this:

using Aspose.Words;
using Aspose.Words.Tables;

public void CopyCellStyles(Document doc, string bookmarkName, Table mainTable)
{
    // Access the bookmark
    Bookmark bookmark = doc.Range.Bookmarks[bookmarkName];
    if (bookmark != null)
    {
        // Get the cell that the bookmark is in
        Cell sourceCell = (Cell)bookmark.BookmarkStart.GetAncestor(NodeType.Cell);
        if (sourceCell != null)
        {
            // Retrieve styles from the source cell
            Font font = sourceCell.CellFormat.Font;
            ParagraphFormat paragraphFormat = sourceCell.Paragraphs[0].ParagraphFormat;
            CellFormat cellFormat = sourceCell.CellFormat;

            // Find the corresponding cell in the main table
            // Assuming you have a way to identify the corresponding cell
            Cell targetCell = mainTable.Rows[0].Cells[0]; // Example: first cell of the first row

            // Apply the styles to the target cell
            targetCell.CellFormat.Font = font;
            targetCell.Paragraphs[0].ParagraphFormat = paragraphFormat;
            targetCell.CellFormat = cellFormat;
        }
    }
}

Explanation:

  • The code accesses a bookmark by its name and retrieves the cell associated with that bookmark.
  • It then extracts the font, paragraph format, and cell format from the source cell.
  • Finally, it applies these styles to the corresponding cell in the main table.

Make sure to adjust the logic for finding the corresponding cell in the main table based on your specific requirements.

This approach allows you to maintain consistent styling across different tables in your document based on the bookmarked cells.

This didn’t work. cellFormat does not have a definition for Font. And also this code is taking the style of first cell and applies it to all the cells of that row

@WJobin Could you please attach your input document and expected output? We will check your documents and provide you more information.

@alexey.noskov
sampleInputDoc.docx (19.5 KB)

sampleOutputDoc.docx (21.1 KB)

I have attached the input and expected documents.
Here my intention is to take the font, paragraph, cell styles of each bookmarked cells from the last section “Table Styles”. And apply these styles and create a valid table in the mergeField “FleetList”.
And finally remove the last section where Table Styles are stored.

@WJobin Thank you for additional information. Why don’t you simply define the required table in the template at the desired located and fill it with data instead of copying the table from one pace to another in your document? Have you considered using Mail Merge with Regions.

@alexey.noskov
My table have a lot of customizations dynamically, so I can’t use it.
In my approach everything works fine (i.e. populating data and the deletion of the last section containing style table). Only problem is while copying the styles, always the style of first cell in a row is copied. That is, the style of “Header1” column is copied for all headers. And the style of “Body1” column is copied for all body

@WJobin Could you please provide your code that will demonstrate your technique and allow us to reproduce the problem? We will check it and provide you more information.

public static void ApplyTableCellTextBookmarkStyle(Document doc, DocumentBuilder builder, string bookmarkName)
{

    // Get the bookmark
    Bookmark bookmark = doc.Range.Bookmarks[bookmarkName];

    if (bookmark == null) return;

    builder.Font.ClearFormatting();
    builder.ParagraphFormat.ClearFormatting();
    builder.CellFormat.ClearFormatting();

    // Get the parent paragraph of the bookmark
    Paragraph para = bookmark.BookmarkStart.GetAncestor(NodeType.Paragraph) as Paragraph;
    if (para != null && para.Runs.Count > 0)
    {
        // Get the first run in the paragraph
        Run run = para.Runs[0];

        // Copy font properties manually
        builder.Font.Name = run.Font.Name;
        builder.Font.Size = run.Font.Size;
        builder.Font.Bold = run.Font.Bold;
        builder.Font.Italic = run.Font.Italic;
        builder.Font.Color = run.Font.Color;
        builder.Font.Underline = run.Font.Underline;
        builder.Font.StrikeThrough = run.Font.StrikeThrough;
        builder.Font.Subscript = run.Font.Subscript;
        builder.Font.Superscript = run.Font.Superscript;
        builder.Font.Shadow = run.Font.Shadow;
        builder.Font.SmallCaps = run.Font.SmallCaps;
        builder.Font.AllCaps = run.Font.AllCaps;

        // Copy paragraph properties manually
        builder.ParagraphFormat.Alignment = para.ParagraphFormat.Alignment;
        builder.ParagraphFormat.LeftIndent = para.ParagraphFormat.LeftIndent;
        builder.ParagraphFormat.RightIndent = para.ParagraphFormat.RightIndent;
        builder.ParagraphFormat.SpaceBefore = para.ParagraphFormat.SpaceBefore;
        builder.ParagraphFormat.SpaceAfter = para.ParagraphFormat.SpaceAfter;
        builder.ParagraphFormat.LineSpacing = para.ParagraphFormat.LineSpacing;
        builder.ParagraphFormat.FirstLineIndent = para.ParagraphFormat.FirstLineIndent;
        builder.ParagraphFormat.KeepWithNext = para.ParagraphFormat.KeepWithNext;
        builder.ParagraphFormat.KeepTogether = para.ParagraphFormat.KeepTogether;
        builder.ParagraphFormat.PageBreakBefore = para.ParagraphFormat.PageBreakBefore;
        builder.ParagraphFormat.WidowControl = para.ParagraphFormat.WidowControl;
        builder.ParagraphFormat.Shading.BackgroundPatternColor = para.ParagraphFormat.Shading.BackgroundPatternColor;
        builder.ParagraphFormat.Borders.Color = para.ParagraphFormat.Borders.Color;
        builder.ParagraphFormat.Borders.LineWidth = para.ParagraphFormat.Borders.LineWidth;
    }
    else
    {
        /*No text found in the bookmark.*/
    }

    // Get the parent cell of the bookmark
    Cell cell = bookmark.BookmarkStart.GetAncestor(NodeType.Cell) as Cell;
    if (cell != null)
    {
        // Copy cell properties manually
        builder.CellFormat.Width = cell.CellFormat.Width;
        builder.CellFormat.Orientation = cell.CellFormat.Orientation;
        builder.CellFormat.VerticalAlignment = cell.CellFormat.VerticalAlignment;
        builder.CellFormat.WrapText = cell.CellFormat.WrapText;
        builder.CellFormat.FitText = cell.CellFormat.FitText;
        builder.CellFormat.LeftPadding = cell.CellFormat.LeftPadding;
        builder.CellFormat.RightPadding = cell.CellFormat.RightPadding;
        builder.CellFormat.TopPadding = cell.CellFormat.TopPadding;
        builder.CellFormat.BottomPadding = cell.CellFormat.BottomPadding;
        builder.CellFormat.Borders.Color = cell.CellFormat.Borders.Color;
        builder.CellFormat.Borders.LineWidth = cell.CellFormat.Borders.LineWidth;
        builder.CellFormat.Shading.BackgroundPatternColor = cell.CellFormat.Shading.BackgroundPatternColor;
    }
}

And I call this function “ApplyTableCellTextBookmarkStyle” before inserting the cell in the table generation code.
i.e.

builder.InsertCell();
builder.Write(value);

@WJobin Thank you for additional information. The problem occurs because physically all your bookmarks starts in the first cell of your table:


In document.xml this looks like this:

<w:tc>
	<w:tcPr>
		<w:tcW w:w="815" w:type="dxa"/>
		<w:shd w:val="clear" w:color="auto" w:fill="8EAADB" w:themeFill="accent1" w:themeFillTint="99"/>
	</w:tcPr>
	<w:p w14:paraId="319A1CDC" w14:textId="4F718909" w:rsidR="00650261" w:rsidRPr="002702A9" w:rsidRDefault="006816BF" w:rsidP="00876383">
		<w:pPr>
			<w:tabs>
				<w:tab w:val="left" w:pos="1418"/>
			</w:tabs>
			<w:rPr>
				<w:rFonts w:ascii="Algerian" w:hAnsi="Algerian" w:cs="Arial"/>
				<w:color w:val="FFFFFF" w:themeColor="background1"/>
				<w:sz w:val="18"/>
				<w:szCs w:val="18"/>
				<w:lang w:val="en-GB"/>
			</w:rPr>
		</w:pPr>
		<w:bookmarkStart w:id="1" w:name="FleetListTable_Header_IMO" w:colFirst="1" w:colLast="1"/>
		<w:bookmarkStart w:id="2" w:name="FleetListTable_Header_Class" w:colFirst="5" w:colLast="5"/>
		<w:bookmarkStart w:id="3" w:name="FleetListTable_Header_No" w:colFirst="0" w:colLast="0"/>
		<w:bookmarkStart w:id="4" w:name="FleetListTable_Header_Vessel" w:colFirst="2" w:colLast="2"/>
		<w:bookmarkStart w:id="5" w:name="FleetListTable_Header_Type" w:colFirst="3" w:colLast="3"/>
		<w:bookmarkStart w:id="6" w:name="FleetListTable_Header_Built" w:colFirst="4" w:colLast="4"/>
		<w:bookmarkStart w:id="7" w:name="FleetListTable_Header_GT" w:colFirst="6" w:colLast="6"/>
		<w:bookmarkStart w:id="8" w:name="FleetListTable_Header_Size" w:colFirst="8" w:colLast="8"/>
		<w:bookmarkStart w:id="9" w:name="FleetListTable_Header_Flag" w:colFirst="9" w:colLast="9"/>
		<w:bookmarkStart w:id="10" w:name="FleetListTable_Header_Dwt" w:colFirst="7" w:colLast="7"/>
		<w:bookmarkStart w:id="11" w:name="FleetListTable"/>
		<w:r>
			<w:rPr>
				<w:rFonts w:ascii="Algerian" w:hAnsi="Algerian" w:cs="Arial"/>
				<w:color w:val="FFFFFF" w:themeColor="background1"/>
				<w:sz w:val="18"/>
				<w:szCs w:val="18"/>
				<w:lang w:val="en-GB"/>
			</w:rPr>
			<w:t>Header1</w:t>
		</w:r>
	</w:p>
</w:tc>

So when you get paragraph and cell ancestors of the bookmark start in your code you always get the first cell.
Bookmark class inn Aspose.Words has special properties that indicate that bookmark is a column bookmark. Please see Bookmark.IsColumn, Bookmark.FirstColumn and Bookmark.LastColumn properties. To get the right cell in your code please try using the following code:

// Get the parent paragraph of the bookmark
Paragraph para = bookmark.BookmarkStart.GetAncestor(NodeType.Paragraph) as Paragraph;
// Get the parent cell of the bookmark
Cell cell = bookmark.BookmarkStart.GetAncestor(NodeType.Cell) as Cell;
// Check if bookmark is column bookmark.
if (bookmark.IsColumn)
{
    // Get cell and paragraph by the first column index of the bookmark.
    Row parentRow = bookmark.BookmarkStart.GetAncestor(NodeType.Row) as Row;
    if (parentRow != null)
    {
        cell = parentRow.Cells[bookmark.FirstColumn];
        para = cell.FirstParagraph;
    }
}
1 Like

@alexey.noskov Great!! that is what i was looking for. Thank you so much

1 Like