Manage Table Cells in Presentations Using C++
Overview
Aspose.Slides allows you to access and modify table cells in PowerPoint presentations. This article explains how to identify merged table cells, remove cell borders, work with cell numbering after merging or splitting cells, change a cell’s background color, and add an image inside a table cell. The examples show how to create or open a presentation, get a table from a slide, update cell formatting through cell properties, and save the modified presentation as a PPTX file.
Aspose.Slides uses zero-based indices to access table cells in the order (column, row).
Identify a Merged Table Cell
The example opens an existing presentation and accesses the first shape on the first slide as a table. It assumes that the slide and shape exist and that the shape is a table. It then iterates through all rows and columns and uses get_IsMergedCell to identify cells in merged regions. For each match, it prints the cell coordinates in row;column order, get_RowSpan, get_ColSpan, and the region’s starting coordinates, get_FirstRowIndex and get_FirstColumnIndex.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/Table/ITable.h>
#include <DOM/Table/ICell.h>
#include <system/smart_ptr.h>
#include <DOM/Table/IRowCollection.h>
#include <DOM/Table/IColumnCollection.h>
#include <system/console.h>
using namespace Aspose::Slides;
using namespace System;
auto presentation = MakeObject<Presentation>(u"presentation_with_table.pptx");
auto slide = presentation->get_Slide(0);
auto table = ExplicitCast<ITable>(slide->get_Shape(0));
auto rowCount = table->get_Rows()->get_Count();
for (auto rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
auto columnCount = table->get_Columns()->get_Count();
for (auto columnIndex = 0; columnIndex < columnCount; columnIndex++)
{
auto cell = table->idx_get(columnIndex, rowIndex);
if (cell->get_IsMergedCell())
{
Console::WriteLine(u"Cell {0};{1} belongs to a merged region with RowSpan={2} and ColSpan={3} starting at {4};{5}.", rowIndex, columnIndex, cell->get_RowSpan(), cell->get_ColSpan(), cell->get_FirstRowIndex(), cell->get_FirstColumnIndex());
}
}
}
Remove Table Cell Borders
Create a Presentation and add a table to its first slide with AddTable. Column widths, row heights, and the table position are specified in points. The example sets all four cell borders to FillType::NoFill, making them invisible.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/Table/ITable.h>
#include <DOM/Table/ICell.h>
#include <system/smart_ptr.h>
#include <DOM/FillType.h>
#include <DOM/ILineFormat.h>
#include <DOM/ILineFillFormat.h>
#include <DOM/Table/ICellFormat.h>
#include <DOM/Table/IRow.h>
#include <DOM/Table/IRowCollection.h>
#include <system/enumerator_adapter.h>
#include <Export/SaveFormat.h>
#include <system/array.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto columnWidths = MakeArray<double>({50, 50, 50, 50});
auto rowHeights = MakeArray<double>({50, 30, 30, 30, 30});
auto table = slide->get_Shapes()->AddTable(100, 50, columnWidths, rowHeights);
for (const auto& row : IterateOver(table->get_Rows()))
for (const auto& cell : IterateOver(row))
{
cell->get_CellFormat()->get_BorderTop()->get_FillFormat()->set_FillType(FillType::NoFill);
cell->get_CellFormat()->get_BorderBottom()->get_FillFormat()->set_FillType(FillType::NoFill);
cell->get_CellFormat()->get_BorderLeft()->get_FillFormat()->set_FillType(FillType::NoFill);
cell->get_CellFormat()->get_BorderRight()->get_FillFormat()->set_FillType(FillType::NoFill);
}
presentation->Save(u"table.pptx", SaveFormat::Pptx);
Merge Table Cells
Use MergeCells to combine a rectangular range of table cells into one cell. Specify the cells at the top-left and bottom-right corners of the range. The final argument controls whether the merge may include cells outside the specified range; false keeps the merge within that range.
The example creates a 4-by-4 table with 70-point columns and rows, then merges the four central cells from (1, 1) through (2, 2). The resulting cell spans two columns and two rows, while the table’s underlying grid retains four columns and four rows. To access the merged cell’s content or formatting, use its top-left position: table->idx_get(1, 1) in this example. The other positions in the merged range remain part of the table grid, so the indices of cells outside the range do not change.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/Table/ITable.h>
#include <DOM/Table/ICell.h>
#include <system/smart_ptr.h>
#include <Export/SaveFormat.h>
#include <system/array.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto columnWidths = MakeArray<double>({70, 70, 70, 70});
auto rowHeights = MakeArray<double>({70, 70, 70, 70});
auto table = slide->get_Shapes()->AddTable(100, 50, columnWidths, rowHeights);
table->MergeCells(table->idx_get(1, 1), table->idx_get(2, 2), false);
presentation->Save(u"merged_cells.pptx", SaveFormat::Pptx);
Split Table Cells
Merging cells in the previous example preserves the table’s grid. Splitting a cell can introduce a new grid column and change the column indices of cells to its right. Aspose.Slides follows PowerPoint’s table grid model.
This example creates a 4-by-4 table with 70-point columns and rows and calls SplitByWidth on cell (1, 1). Half of the cell’s 70-point width is passed to create two equal-width cells.
After this split, the two halves are accessed as table->idx_get(1, 1) and table->idx_get(2, 1). The table grid now has five columns: cells originally in columns 2 and 3 move to columns 3 and 4, respectively. Row indices remain unchanged. Use these updated column indices when accessing cells after the split.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/Table/ITable.h>
#include <DOM/Table/ICell.h>
#include <system/smart_ptr.h>
#include <Export/SaveFormat.h>
#include <system/array.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto columnWidths = MakeArray<double>({70, 70, 70, 70});
auto rowHeights = MakeArray<double>({70, 70, 70, 70});
auto table = slide->get_Shapes()->AddTable(100, 50, columnWidths, rowHeights);
table->idx_get(1, 1)->SplitByWidth(table->idx_get(1, 1)->get_Width() / 2);
presentation->Save(u"split_cells.pptx", SaveFormat::Pptx);
Split Merged Cells by Row or Column Span
To prepare merged template cells for data population, use SplitByRowSpan to split along an existing row boundary, or SplitByColSpan to split along a column boundary.
The index argument counts rows in the upper part or columns in the left part of the split; it is relative to the merged region:
- Row split:
0 < index <get_RowSpan. - Column split:
0 < index <get_ColSpan.
The example expects a presentation to have a table as the first shape on the first slide, with (1, 2) and (1, 3) merged vertically. Starting from the lower position, it uses get_FirstColumnIndex and get_FirstRowIndex to locate the origin and checks both spans. SplitByRowSpan(1) then separates rows 2 and 3 for product names. For a horizontal two-column merge, use SplitByColSpan(1) instead.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/Table/ITable.h>
#include <DOM/Table/ICell.h>
#include <system/smart_ptr.h>
#include <DOM/ITextFrame.h>
#include <system/console.h>
#include <Export/SaveFormat.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>(u"table_template.pptx");
auto slide = presentation->get_Slide(0);
auto table = ExplicitCast<ITable>(slide->get_Shape(0));
auto selectedCell = table->idx_get(1, 3);
auto firstColumnIndex = selectedCell->get_FirstColumnIndex();
auto firstRowIndex = selectedCell->get_FirstRowIndex();
auto mergedCell = table->idx_get(firstColumnIndex, firstRowIndex);
if (mergedCell->get_IsMergedCell() && mergedCell->get_RowSpan() == 2 && mergedCell->get_ColSpan() == 1)
{
mergedCell->SplitByRowSpan(1);
// Retrieve the resulting cells from the table after splitting.
auto upperCell = table->idx_get(firstColumnIndex, firstRowIndex);
auto lowerCell = table->idx_get(firstColumnIndex, firstRowIndex + 1);
Console::WriteLine(u"Upper cell merged: {0}", upperCell->get_IsMergedCell());
Console::WriteLine(u"Lower cell merged: {0}", lowerCell->get_IsMergedCell());
upperCell->get_TextFrame()->set_Text(u"Product A");
lowerCell->get_TextFrame()->set_Text(u"Product B");
presentation->Save(u"split_template.pptx", SaveFormat::Pptx);
}
else
{
Console::WriteLine(u"Select a merged region spanning exactly two rows and one column.");
}
The table grid and surrounding cell indices stay unchanged. Retrieve the resulting cells by their coordinates; here, both have spans of 1 and get_IsMergedCell prints False. Larger regions can remain partly merged after one split.
The original text and its formatting remain in the upper (or left) cell; the new cell is empty but inherits cell formatting such as fill, borders, and margins. Populate the cells after splitting and set any required text formatting explicitly.
The saved presentation contains separate “Product A” and “Product B” cells with the template’s cell formatting retained. See the Cell API Reference for details.
Change the Table Cell Background Color
This example creates a table with 150-point columns and 50-point rows. It uses set_FillType to select a solid fill and get_SolidFillColor to access the fill color and set it to red for cell (2, 3), in the third column and fourth row.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/Table/ITable.h>
#include <DOM/Table/ICell.h>
#include <system/smart_ptr.h>
#include <DOM/FillType.h>
#include <DOM/IColorFormat.h>
#include <DOM/IFillFormat.h>
#include <DOM/Table/ICellFormat.h>
#include <drawing/color.h>
#include <Export/SaveFormat.h>
#include <system/array.h>
using namespace System::Drawing;
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto columnWidths = MakeArray<double>({150, 150, 150, 150});
auto rowHeights = MakeArray<double>({50, 50, 50, 50, 50});
auto table = slide->get_Shapes()->AddTable(50, 50, columnWidths, rowHeights);
auto cell = table->idx_get(2, 3);
cell->get_CellFormat()->get_FillFormat()->set_FillType(FillType::Solid);
cell->get_CellFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Red());
presentation->Save(u"cell_background_color.pptx", SaveFormat::Pptx);
Add an Image Inside a Table Cell
Place the input image in the working directory before running this example. It loads the image with Images::FromFile and adds it to the presentation’s image collection with AddImage. It then assigns the image to the picture fill of cell (0, 0), the first cell in the table.
PictureFillMode::Stretch stretches the image to fill the cell, which may change its aspect ratio. Column widths and row heights are in points. The loaded image is disposed after it has been added to the presentation.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/Table/ITable.h>
#include <DOM/Table/ICell.h>
#include <system/smart_ptr.h>
#include <DOM/FillType.h>
#include <DOM/IImageCollection.h>
#include <IImage.h>
#include <DOM/IPPImage.h>
#include <DOM/IFillFormat.h>
#include <DOM/IPictureFillFormat.h>
#include <DOM/ISlidesPicture.h>
#include <DOM/PictureFillMode.h>
#include <DOM/Table/ICellFormat.h>
#include <Util/Images.h>
#include <Export/SaveFormat.h>
#include <system/array.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto columnWidths = MakeArray<double>({150, 150, 150, 150});
auto rowHeights = MakeArray<double>({100, 100, 100, 100, 90});
auto table = slide->get_Shapes()->AddTable(50, 50, columnWidths, rowHeights);
auto image = Images::FromFile(u"aspose_logo.jpg");
auto ppImage = presentation->get_Images()->AddImage(image);
image->Dispose();
table->idx_get(0, 0)->get_CellFormat()->get_FillFormat()->set_FillType(FillType::Picture);
table->idx_get(0, 0)->get_CellFormat()->get_FillFormat()->get_PictureFillFormat()->set_PictureFillMode(PictureFillMode::Stretch);
table->idx_get(0, 0)->get_CellFormat()->get_FillFormat()->get_PictureFillFormat()->get_Picture()->set_Image(ppImage);
presentation->Save(u"table_cell_with_image.pptx", SaveFormat::Pptx);
FAQ
Can I set different line thicknesses and styles for different sides of a single cell?
Yes. The top/bottom/left/right borders have separate properties, so the thickness and style of each side can differ.
What happens to the image if I change the column/row size after setting a picture as the cell’s background?
The behavior depends on the fill mode (stretch/tile). With stretching, the image adjusts to the new cell; with tiling, the tiles are recalculated.
Can I assign a hyperlink to all the content of a cell?
Hyperlinks are set at the text (portion) level inside the cell’s text frame or at the level of the entire table/shape. In practice, you assign the link to a portion or to all the text in the cell.
Can I set different fonts within a single cell?
Yes. A cell’s text frame supports portions (runs) with independent formatting—font family, style, size, and color.