#63017 - Remove rows from a XSLFTable

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1849244 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2018-12-18 22:52:36 +00:00
parent 2dea9797ce
commit 9eea29da5b
5 changed files with 138 additions and 19 deletions

View File

@ -143,7 +143,7 @@ public class DrawPaint {
public Paint getPaint(Graphics2D graphics, PaintStyle paint, PaintModifier modifier) {
if (modifier == PaintModifier.NONE) {
return null;
return TRANSPARENT;
}
if (paint instanceof SolidPaint) {
return getSolidPaint((SolidPaint)paint, graphics, modifier);
@ -152,7 +152,7 @@ public class DrawPaint {
} else if (paint instanceof TexturePaint) {
return getTexturePaint((TexturePaint)paint, graphics);
}
return null;
return TRANSPARENT;
}
@SuppressWarnings({"WeakerAccess", "unused"})
@ -236,7 +236,7 @@ public class DrawPaint {
protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
InputStream is = fill.getImageData();
if (is == null) {
return null;
return TRANSPARENT;
}
assert(graphics != null);
@ -250,7 +250,7 @@ public class DrawPaint {
}
} catch (IOException e) {
LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", e);
return null;
return TRANSPARENT;
}
int alpha = fill.getAlpha();
@ -270,7 +270,7 @@ public class DrawPaint {
if(image == null) {
LOG.log(POILogger.ERROR, "Can't load image data");
return null;
return TRANSPARENT;
}
return new java.awt.TexturePaint(image, textAnchor);

View File

@ -121,7 +121,10 @@ public class DrawShape implements Drawable {
}
public static Rectangle2D getAnchor(Graphics2D graphics, PlaceableShape<?,?> shape) {
// return getAnchor(graphics, shape.getAnchor());
final Rectangle2D shapeAnchor = shape.getAnchor();
if (shapeAnchor == null) {
return null;
}
final boolean isHSLF = isHSLF(shape);
AffineTransform tx = graphics == null ? null : (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
@ -146,7 +149,6 @@ public class DrawShape implements Drawable {
// and later on, turn it around again to compare it with its original size ...
final Rectangle2D shapeAnchor = shape.getAnchor();
final Rectangle2D anchorO = tx.createTransformedShape(shapeAnchor).getBounds2D();
final Rectangle2D anchorT;
@ -190,7 +192,7 @@ public class DrawShape implements Drawable {
normalizedShape = txs2.createTransformedShape(shapeAnchor).getBounds2D();
}
} else {
normalizedShape = shape.getAnchor();
normalizedShape = shapeAnchor;
}
if (tx.isIdentity()) {

View File

@ -69,6 +69,10 @@ public class DrawSimpleShape extends DrawShape {
@Override
public void draw(Graphics2D graphics) {
if (getAnchor(graphics, getShape()) == null) {
return;
}
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape());
Paint fill = drawPaint.getPaint(graphics, getShape().getFillStyle().getPaint());
Paint line = drawPaint.getPaint(graphics, getShape().getStrokeStyle().getPaint());

View File

@ -159,6 +159,16 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
return row;
}
/**
* Remove the row on the given index
* @param rowIdx the row index
*/
public void removeRow(int rowIdx) {
_table.removeTr(rowIdx);
_rows.remove(rowIdx);
updateRowColIndexes();
}
static CTGraphicalObjectFrame prototype(int shapeId){
CTGraphicalObjectFrame frame = CTGraphicalObjectFrame.Factory.newInstance();
CTGraphicalObjectFrameNonVisual nvGr = frame.addNewNvGraphicFramePr();
@ -275,12 +285,15 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
}
}
/* package */ void updateCellAnchor() {
/**
* Calculates the bounding boxes of all cells and updates the dimension of the table
*/
public void updateCellAnchor() {
int rows = getNumberOfRows();
int cols = getNumberOfColumns();
double colWidths[] = new double[cols];
double rowHeights[] = new double[rows];
double[] colWidths = new double[cols];
double[] rowHeights = new double[rows];
for (int row=0; row<rows; row++) {
rowHeights[row] = getRowHeight(row);
@ -292,7 +305,8 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
Rectangle2D tblAnc = getAnchor();
DrawFactory df = DrawFactory.getInstance(null);
double newY = tblAnc.getY();
double nextY = tblAnc.getY();
double nextX = tblAnc.getX();
// #1 pass - determine row heights, the height values might be too low or 0 ...
for (int row=0; row<rows; row++) {
@ -312,16 +326,16 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
// #2 pass - init properties
for (int row=0; row<rows; row++) {
double newX = tblAnc.getX();
nextX = tblAnc.getX();
for (int col=0; col<cols; col++) {
Rectangle2D bounds = new Rectangle2D.Double(newX, newY, colWidths[col], rowHeights[row]);
Rectangle2D bounds = new Rectangle2D.Double(nextX, nextY, colWidths[col], rowHeights[row]);
XSLFTableCell tc = getCell(row, col);
if (tc != null) {
tc.setAnchor(bounds);
newX += colWidths[col]+DrawTableShape.borderSize;
nextX += colWidths[col]+DrawTableShape.borderSize;
}
}
newY += rowHeights[row]+DrawTableShape.borderSize;
nextY += rowHeights[row]+DrawTableShape.borderSize;
}
// #3 pass - update merge info
@ -348,5 +362,8 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
}
}
setAnchor(new Rectangle2D.Double(tblAnc.getX(),tblAnc.getY(),
nextX-tblAnc.getX(),
nextY-tblAnc.getY()));
}
}

View File

@ -26,22 +26,118 @@ import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Random;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.TempFile;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.apache.poi.xslf.util.PPTX2PNG;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
public class TestXSLFTable {
@Test
public void testResize() throws Exception {
String[][] data = getDummyData(20);
final int maxHeight = 400;
XMLSlideShow ppt = new XMLSlideShow();
int rowIdx=1;
while (rowIdx<data.length) {
XSLFSlide slide = ppt.createSlide();
// a red bordered box in the background, to show/verify the table dimensions
XSLFAutoShape as = slide.createAutoShape();
as.setShapeType(ShapeType.RECT);
as.setStrokeStyle(Color.RED, 2., StrokeStyle.LineDash.LG_DASH);
XSLFTable tab = slide.createTable(1, data[0].length);
tab.setAnchor(new Rectangle2D.Double(50,50,0,0));
tab.setColumnWidth(0, 60);
tab.setColumnWidth(1, 60);
tab.setColumnWidth(2, 60);
int startRow = rowIdx;
XSLFTableRow row = tab.getRows().get(0);
for (int colIdx=0; colIdx<data[0].length; colIdx++) {
XSLFTextRun tr = row.getCells().get(colIdx).setText(data[0][colIdx]);
tr.setFontSize(20.);
tr.setFontFamily("Arial");
}
while (rowIdx<data.length) {
row = tab.addRow();
for (int col=0; col<data[rowIdx].length; col++) {
XSLFTextRun tr = row.addCell().setText(data[rowIdx][col]);
tr.setFontSize(15.);
tr.setFontFamily("Arial");
}
tab.updateCellAnchor();
if (tab.getAnchor().getHeight() > maxHeight) {
tab.removeRow(rowIdx-startRow);
break;
}
rowIdx++;
}
tab.updateCellAnchor();
as.setAnchor(tab.getAnchor());
}
File fileOut = TempFile.createTempFile("tabtest", "pptx");
try (FileOutputStream fos = new FileOutputStream(fileOut)) {
ppt.write(fos);
}
String[] args = {
"-format", "null", // png,gif,jpg or null for test
"-slide", "-1", // -1 for all
"-outdir", fileOut.getParentFile().getCanonicalPath(),
"-quiet",
fileOut.getAbsolutePath()
};
PPTX2PNG.main(args);
}
private static String[][] getDummyData(int rows) {
String[] header = { "Row#", "ID", "Name", "Description", "Price", "Percent", "Current Value" };
String[][] data = new String[rows+1][header.length];
System.arraycopy(header, 0, data[0], 0, header.length);
String[] names = { "car", "rubber duckie", "phone", "gadget" };
String[] desc = { "new", "used", "untouched" };
Random r = new Random();
for (int row=1; row<=rows; row++) {
String[] line = new String[header.length];
line[0] = Integer.toString(row);
line[1] = Integer.toString(r.nextInt(1000));
line[2] = names[r.nextInt(names.length)];
line[3] = "The "+desc[r.nextInt(desc.length)]+" "+line[2]+" in "+(2017+row);
line[4] = "$"+r.nextInt(50000);
line[5] = r.nextInt(100)+"%";
line[6] = "$"+r.nextInt(50000);
System.arraycopy(line, 0, data[row], 0, header.length);
}
return data;
}
@Test
public void testRead() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");