Cannot split table cell after rowspan merges

Hi,

I have a table with rowspans (cells merged to reflect this). My table can be up to several thousand rows high. When the table reaches the bottom of a slide, I remove the empty rows at the end, and start a new table on the next slide to continue writing data.

I don't know how high each row is until after I have written out the data across all the cells. This means, for example, that I can have cells in the first column that rowspan down 10 rows, but after 6 rows I have run out of room and need to trim the table and start again on the next slide. This is a problem because if I use Table.Rows.RemoveAt() it throws an error because this would delete some cells that are merged to other cells higher up. I understand why this is a problem. What I want to do is to un-merge / split the last 4 cells so I can delete the rows.

I can use merge fine, it generates a table.

I can use split fine, it generates a table. I found SplitByHeight() worked but SplitByRowSpan() would give me errors.

I cannot however use split to un-merge cells that have already been merged. If I do, and then call Table.Rows.RemoveAt() it throws an error. What I want to do, is when I get to the end of row 6, un-merge the last 4 cells so I can delete the rows. Or alternatively, split the entire 10 cells, and just merge 6 together.

Thank-you for your time.



//Access first slide
ISlide sld = _presentation.Slides[0];

//Define columns with widths and rows with heights
double[] dblCols = { 50, 50, 50 };
double[] dblRows = { 50, 50, 50 };

//Add table shape to slide
ITable tbl = sld.Shapes.AddTable(100, 50, dblCols, dblRows);

// rowspan
tbl.MergeCells(tbl[0, 1], tbl[0, 2], false);
//tbl[0, 1].SplitByRowSpan(2);

//tbl.Rows.RemoveAt(2, false);

//Set border format for each cell
foreach (IRow row in tbl.Rows) {
foreach (ICell cell in row) {
cell.BorderTop.FillFormat.FillType = FillType.Solid;
cell.BorderTop.FillFormat.SolidFillColor.Color = Color.Red;
cell.BorderTop.Width = 5;

cell.BorderBottom.FillFormat.FillType = FillType.Solid;
cell.BorderBottom.FillFormat.SolidFillColor.Color = Color.Red;
cell.BorderBottom.Width = 5;

cell.BorderLeft.FillFormat.FillType = FillType.Solid;
cell.BorderLeft.FillFormat.SolidFillColor.Color = Color.Red;
cell.BorderLeft.Width = 5;

cell.BorderRight.FillFormat.FillType = FillType.Solid;
cell.BorderRight.FillFormat.SolidFillColor.Color = Color.Red;
cell.BorderRight.Width = 5;
}
}

Hi David,


Thanks for your interest in Aspose.Slides.

I have observed the requirement shared by you and your issue is that you want to remove last row based on some decision that slide height is exceeded but that last row’s cells are merged some how with valid cells lying in valid slide region. You need to unmerge them so that you may remove only targeted row and move on. Is it the requirement on your end? If yes, then please provide me a sample presentation depicting your scenario in which you want to remove the row. Please also share the snapshot of slide depicting which of cells are merged and that you want to unmerge. Actually, we will have to try using SplitByHeight() or SplitByRowSpan() some way to achieve your goal. Please share the requested information so that I may help you further in this regard.

Many Thanks,

Hi,


I have included the code which shows an example of what I would like to do. The cell text doesn’t matter, I can easily repeat it so it is left out of the example.

The code generates 3 tables. The red table is 15 rows * 3 columns and overflows off the bottom of the slide. The two blue tables, represent what I would like to end up with, a 10 * 3 table and 5 * 3 table.

The easiest way for me to code this is:
- create a 15 * 3 table
- merge the first column of 15 cells
- when I get to row 10 and realise there isn’t any space left, undo the merging of 15 cells, re-merge the first 10, then remove the rows that overflow. I can then repeat the leftover rows on the next table.

I am working on a workaround so that I can attempt to calculate the row height before rendering the table. I am just hoping that I can avoid that if possible.



ISlide sld = _presentation.Slides[0];

double[] dblCols = { 50, 50, 50 }; // 3
double[] dblRows = { 50, 50, 50, 50, 50,
50, 50, 50, 50, 50,
50, 50, 50, 50, 50 }; // 15

int splitAtRowNum = 10;
int rowsRemaining = dblRows.Length - splitAtRowNum;

ITable originalTable = sld.Shapes.AddTable(50, 50, dblCols, dblRows);
PopulateData(originalTable);
originalTable.MergeCells(originalTable[0, 0], originalTable[0, dblRows.Length - 1], false);

AddBorderColors(originalTable, Color.Red);

// show example of table split into two
if (true) {

ITable tableToSplitPart1 = sld.Shapes.AddTable(300, 50, dblCols, dblRows);
PopulateData(tableToSplitPart1);
tableToSplitPart1.MergeCells(tableToSplitPart1[0, 0], tableToSplitPart1[0, splitAtRowNum - 1], false);
RemoveRowsFromTable(tableToSplitPart1, rowsRemaining, true);
AddBorderColors(tableToSplitPart1, Color.Blue);

ITable tableToSplitPart2 = sld.Shapes.AddTable(500, 50, dblCols, dblRows);
PopulateData(tableToSplitPart2);
tableToSplitPart2.MergeCells(tableToSplitPart2[0, splitAtRowNum ], tableToSplitPart2[0, splitAtRowNum + rowsRemaining - 1], false);
RemoveRowsFromTable(tableToSplitPart2, splitAtRowNum, false);
AddBorderColors(tableToSplitPart2, Color.Blue);
}

//
// helper methods
//

private void AddBorderColors(ITable table, Color color) {

foreach (IRow row in table.Rows) {

foreach (ICell cell in row) {

cell.FillFormat.FillType = FillType.Solid;
cell.FillFormat.SolidFillColor.Color = Color.White;

cell.BorderTop.FillFormat.FillType = FillType.Solid;
cell.BorderTop.FillFormat.SolidFillColor.Color = color;
cell.BorderTop.Width = 5;

cell.BorderBottom.FillFormat.FillType = FillType.Solid;
cell.BorderBottom.FillFormat.SolidFillColor.Color = color;
cell.BorderBottom.Width = 5;

cell.BorderLeft.FillFormat.FillType = FillType.Solid;
cell.BorderLeft.FillFormat.SolidFillColor.Color = color;
cell.BorderLeft.Width = 5;

cell.BorderRight.FillFormat.FillType = FillType.Solid;
cell.BorderRight.FillFormat.SolidFillColor.Color = color;
cell.BorderRight.Width = 5;
}
}
}

private void RemoveRowsFromTable(ITable table, int rowsToRemove, bool removeFromEnd) {
int initialRowCount = table.Rows.Count - 1;
for (int i = 0; i < rowsToRemove; i++) {
int removeIdx = removeFromEnd ? initialRowCount - i : 0;
table.Rows.RemoveAt(removeIdx, false);
}
}

private void PopulateData(ITable table) {
for (int r = 0; r < table.Rows.Count; r++) {
for (int c = 0; c < table.Rows[r].Count; c++) {
table[c,r].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FontHeight = 10;
table[c,r].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.FillType = FillType.Solid;
table[c,r].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
table[c,r].TextFrame.Paragraphs[0].Portions[0].Text = string.Format("{0} , {1}", r, c);
}
}
}

Hi David,


Thank you for sharing the sample code. I have worked with the code and generated a presentation with 3 tables on slide. The table in the center is spanned till the slide height and has 10 rows in it instead of 15. Isn’t it what you are looking for in Aspose.Slides to offer you? Can you please share the complete requirement if there is still an issue so that I may investigate and help you further. From your code, I am unable to derive the requirement. Please share the information so that I may help you further in this regard.

Many Thanks,

Hi,


I have created another example. Please disregard previous examples.

The code creates a 5 * 5 table. The top left cell, position 0,0 is merged down 3 cells. The cell is then split twice so it is back to three separate cells.

The code then attempts to put letters in the cells.
- ‘A’ into 0,0
- ‘B’ into 0,1
- ‘C’ into 0,2

If the code uses any position, for any cells that were merged then un-merged, the text always goes in the top cell, in this case, 0,0 In the code example, change the ‘if (true)’ to be false and you can see that without the merging/un-merging, the code puts the letters A, B and C out as expected.

Also, borders are applied to all cells in the final table. The cells that were split, don’t contain a border. The code uses a foreach through the rows and cells, it is like the cells no longer exist and are still merged in the background code. This means as well that the rows can not be deleted. If trying to delete a row the user gets the error 'Some of row’s cells lay outside row.'

ISlide sld = _presentation.Slides[0];

double[] dblCols = { 50, 50, 50, 50, 50 };
double[] dblRows = { 50, 50, 50, 50, 50 };

// create a table 5 * 5
ITable table = sld.Shapes.AddTable(50, 50, dblCols, dblRows);
PopulateData(table);

// merge and unmerge the first cell down a rowspan of 3
if (true) {
table.MergeCells(table[0, 0], table[0, 2], true);
table[0, 0].SplitByRowSpan(2);
table[0, 0].SplitByRowSpan(1);
}

table[0, 0].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FontHeight = 12;
table[0, 0].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.FillType = FillType.Solid;
table[0, 0].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
table[0, 0].TextFrame.Paragraphs[0].Portions[0].Text = string.Format(“A”);

table[0, 1].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FontHeight = 12;
table[0, 1].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.FillType = FillType.Solid;
table[0, 1].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
table[0, 1].TextFrame.Paragraphs[0].Portions[0].Text = string.Format(“B”);

table[0, 2].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FontHeight = 12;
table[0, 2].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.FillType = FillType.Solid;
table[0, 2].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
table[0, 2].TextFrame.Paragraphs[0].Portions[0].Text = string.Format(“C”);

AddBorderColors(table, Color.Red);

//
// helper methods
//

private void AddBorderColors(ITable table, Color color) {

foreach (IRow row in table.Rows) {

foreach (ICell cell in row) {

cell.FillFormat.FillType = FillType.Solid;
cell.FillFormat.SolidFillColor.Color = Color.White;

cell.BorderTop.FillFormat.FillType = FillType.Solid;
cell.BorderTop.FillFormat.SolidFillColor.Color = color;
cell.BorderTop.Width = 5;

cell.BorderBottom.FillFormat.FillType = FillType.Solid;
cell.BorderBottom.FillFormat.SolidFillColor.Color = color;
cell.BorderBottom.Width = 5;

cell.BorderLeft.FillFormat.FillType = FillType.Solid;
cell.BorderLeft.FillFormat.SolidFillColor.Color = color;
cell.BorderLeft.Width = 5;

cell.BorderRight.FillFormat.FillType = FillType.Solid;
cell.BorderRight.FillFormat.SolidFillColor.Color = color;
cell.BorderRight.Width = 5;
}
}
}

private void PopulateData(ITable table) {
for (int r = 0; r < table.Rows.Count; r++) {
for (int c = 0; c < table.Rows[r].Count; c++) {
table[c,r].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FontHeight = 10;
table[c,r].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.FillType = FillType.Solid;
table[c,r].TextFrame.Paragraphs[0].Portions[0].PortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
table[c,r].TextFrame.Paragraphs[0].Portions[0].Text = string.Format("{0} , {1}", c, r);
}
}
}

Hi David,

Thank you for sharing the detailed elaboration of the incurring issue. I have worked with the sample code shared and have also developed understanding of your explanation. I have been able to observe that if the cells are merged together say (0,0), (0,1) and (0,2), they are pointed to cell (0,0) no matter cell (0,1) and (0,2) are used. This is logical. However, the issue occurs when the same merged cells are um-merged. Even afters splitting cells the indices of cells (0,1) and (0,2) still points to cell (0,0), which is wrong. This issue of indices may incur issue even when you try to remove the rows with such splitted cells. An issue with ID SLIDESNET-36769 has been created in our issue tracking system to further investigate and resolve the issue. This thread has been linked with the issue so that you may be automatically notified once the issue will be fixed.

We are sorry for your inconvenience,

Hi Mudassir,


thank-you for your great customer service. I will keep an eye on the ticket.

The issues you have found earlier (filed as SLIDESNET-36769) have been fixed in this update.


This message was posted using Notification2Forum from Downloads module by Aspose Notifier.