You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by Simon Davey <si...@simondavey.me.uk> on 2022/02/17 11:39:16 UTC
POI XSLFTable::mergeCells ineffective in single column tables
Hi POI team,
We have found an issue where the POI XSLFTable::mergeCells method seems
ineffective at setting rowspans if the table only has a single column.
We have seen that POI is setting the rowspan=... attribute in the output
Slide XML, however MS PowerPoint is ignoring it. Trying the same cell
merging manually in PowerPoint reveals that instead of setting rowspan,
PowerPoint will remove the spanned-over rows and set the height of the
first row to the total of the spanned over rows.
This makes me wonder if the POI XSLFTable::mergeCells method needs an
update to mimick this technique?
Here's a java testcase showing the problem and our workaround:
=== BEGIN TestMergeCells.java ===
import java.awt.Color;
import java.awt.Rectangle;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTable;
import org.apache.poi.xslf.usermodel.XSLFTableCell;
import org.apache.poi.xslf.usermodel.XSLFTableRow;
/**
* Demonstrate problem with mergeCell rowspan in single column table
* (POI writes out the rowspan=... to XML, but MS PowerPoint ignores it)
*/
public final class TestMergeCells {
private TestMergeCells() {}
// Populate a table
private static void fillTable(XSLFTable tbl, int numRows, int
numColumns, Color clr) {
for (int r = 0; r < numRows; r++) {
XSLFTableRow tr = tbl.addRow();
tr.setHeight(50);
for (int c = 0; c < numColumns; c++) {
XSLFTableCell cell = tr.addCell();
cell.setText("Row" + r + " Col" + c);
cell.setBorderColor(BorderEdge.bottom, clr);
cell.setBorderColor(BorderEdge.left, clr);
cell.setBorderColor(BorderEdge.top, clr);
cell.setBorderColor(BorderEdge.right, clr);
}
}
}
// Workaround function - should POI be doing this internally?
private static void mergeCellsMod(XSLFTable tbl, int fromRow, int
toRow, int fromCol, int toCol) {
if (tbl.getNumberOfColumns() == 1) {
double h = tbl.getRowHeight(fromRow);
// accumulate spanned-over row heights as we remove them
for (int r = toRow; r > fromRow; --r) {
h += tbl.getRowHeight(r);
tbl.removeRow(r);
}
tbl.setRowHeight(fromRow, h);
}
else {
tbl.mergeCells(fromRow, toRow, fromCol, toCol);
}
}
public static void main(String[] args) throws IOException{
try (XMLSlideShow ppt = new XMLSlideShow()) {
XSLFSlide slide = ppt.createSlide();
// Red table has 2 columns, shows that merging rows works (and in
2nd column we demonstrate workaround function)
XSLFTable ta = slide.createTable();
ta.setAnchor(new Rectangle(50, 50, 300, 200));
fillTable(ta, 4, 2, Color.red); // 4 rows, 2 cols
// Blue Table has 1 column, shows that mergeCells is ineffective
here when viewed in MS PowerPoint v2108
XSLFTable tb = slide.createTable();
tb.setAnchor(new Rectangle(400, 50, 150, 200));
fillTable(tb, 4, 1, Color.blue); // 4 rows, 1 col
// Green table, demonstrate basic workaround technique for row
spans in single column tables
XSLFTable tc = slide.createTable();
tc.setAnchor(new Rectangle(200, 300, 150, 200));
fillTable(tc, 4, 1, Color.green); // 4 rows, 1 col
tc.removeRow(2);
tc.setRowHeight(1, 100); // set height to 2x50
// Magenta table demonstrates use a function to apply the workaround
XSLFTable td = slide.createTable();
td.setAnchor(new Rectangle(500, 300, 150, 200));
fillTable(td, 4, 1, Color.magenta); // 4 rows, 1 col
// Merge middle cells in first columns
ta.mergeCells(1,2,0,0); // has the desired effect in 2-col table
mergeCellsMod(ta, 0,1,1,1); // test workaround function on 2-col
table
mergeCellsMod(ta, 2,3,1,1); // ...and again
tb.mergeCells(1,2,0,0); // MS PowerPoint ignores rowspan request
in single column table!
mergeCellsMod(td, 1, 2, 0, 0); // Workaround function is
effective though
try (FileOutputStream out = new
FileOutputStream("TestMergeCells.pptx")) {
ppt.write(out);
}
}
}
}
=== END TestMergeCells.java ===
Thanks (and sorry if I've submitted this report/observation/suggestion
the wrong way!),
Simon Davey
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org