]> source.dussan.org Git - poi.git/commitdiff
#63017 - Remove rows from a XSLFTable
authorAndreas Beeker <kiwiwings@apache.org>
Tue, 18 Dec 2018 22:52:36 +0000 (22:52 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Tue, 18 Dec 2018 22:52:36 +0000 (22:52 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1849244 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/sl/draw/DrawPaint.java
src/java/org/apache/poi/sl/draw/DrawShape.java
src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java

index 80c5bcb00bdec831b4bc2b022e0cf245856388d8..4fda618d0e52c2e303ab79efe7abb2726d6cc3a9 100644 (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);
index df5960b538cc107992c27cd18d44980ff5544180..0c6054c8a99642551a946649fe655892cae4458f 100644 (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()) {
index a8d6fb534e7d5a777579dc53b8c4ad899d39c312..eacc6ed80666b1652b6edf9ce406f75938ee9154 100644 (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());
index c8624f071a127d93c877d578cbf37b1c7fe0faf8..5266c13c09b385d3cffaefecc2bbba2038a3d6f3 100644 (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
@@ -347,6 +361,9 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
                 tc.setAnchor(mergedBounds);
             }
         }
-        
+
+        setAnchor(new Rectangle2D.Double(tblAnc.getX(),tblAnc.getY(),
+                nextX-tblAnc.getX(),
+                nextY-tblAnc.getY()));
     }
 }
index 1df72597d5eeb0029d0534b2183d7295e177168c..498f302dec80e3d6cfe0343842c2c2d1440e55b6 100644 (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");