Bug 45633

Summary: PPT Table problem
Product: POI Reporter: Constantin <cvolozhin>
Component: HSLFAssignee: POI Developers List <dev>
Status: RESOLVED WONTFIX    
Severity: normal    
Priority: P1    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Attachments: PPT file
Result file screenshot

Description Constantin 2008-08-14 06:56:29 UTC
Created attachment 22447 [details]
PPT file

Wrong table cells position in slide. Relative to slide coorditates, not to table. POI code taken from SVN trunk a couple days ago.

Code snippet here:

import java.io.*;

import org.apache.poi.hslf.model.*;
import org.apache.poi.hslf.usermodel.*;


public class JustPOI {

    public static void main(String[] args) {


        SlideShow ppt = null;
        
        try {
            ppt = new SlideShow(new FileInputStream("PST.ppt"));
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
        
        Slide slide = ppt.getSlides()[0];
        Shape shape = slide.getShapes()[2];

        // Create table data array
        
        String[] row1 = new String[3];
        row1[0] = "Project Name";
        row1[1] = "ProjectID";
        row1[2] = "Priority";
        
        String[] row2 = new String[3];
        row2[0] = "Test Work";
        row2[1] = "-";
        row2[2] = "-";

        String[][] tableData = new String[2][3];
        tableData[0] = row1;
        tableData[1] = row2;
        
        Table pptTable = new Table(2, 3);
        
        for (int i = 0; i < pptTable.getNumberOfRows(); i++) {
            String[] rowData = tableData[i];
            for (int j = 0; j < pptTable.getNumberOfColumns(); j++) {
                TableCell pptCell = pptTable.getCell(i, j);
                    String cellData = rowData[j];
                    if (cellData != null) {
                        pptCell.setText(cellData);
                        RichTextRun rt = pptCell.getTextRun().getRichTextRuns()[0];
                        rt.setFontName("Arial");
                        rt.setFontSize(10);
                    }
            }
        }
        
        pptTable.setAnchor(shape.getAnchor());
        
        slide.removeShape(shape);
        slide.addShape(pptTable);
        
        try {
            ppt.write(new FileOutputStream("PST_out.ppt"));
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }

        
    }

}
Comment 1 Constantin 2008-08-14 07:01:32 UTC
Created attachment 22448 [details]
Result file screenshot

in Microsoft Powerpoint 2002
Comment 2 Yegor Kozlov 2008-08-18 11:24:23 UTC
I would say it's a feature of HSLF, not a bug.
In PowerPoint table is a special group of shapes that must be tightly packed and follow certain layout constraints. When you call Table.setAnchor then only the Table's anchor is updated. The anchors of child table cells remain the same and that is why PowerPoint displays it incorrectly.

Below is a workaround:

    public static void main(String[] args) {


        SlideShow ppt = null;

        try {
            ppt = new SlideShow(new FileInputStream("PST.ppt"));
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }

        Slide slide = ppt.getSlides()[0];
        Shape shape = slide.getShapes()[2];
        Rectangle anchor = shape.getAnchor();

        // Create table data array

        String[] row1 = new String[3];
        row1[0] = "Project Name";
        row1[1] = "ProjectID";
        row1[2] = "Priority";

        String[] row2 = new String[3];
        row2[0] = "Test Work";
        row2[1] = "-";
        row2[2] = "-";

        String[][] tableData = new String[2][3];
        tableData[0] = row1;
        tableData[1] = row2;

        Table pptTable = new Table(2, 3);

        for (int i = 0; i < pptTable.getNumberOfRows(); i++) {
            String[] rowData = tableData[i];
            for (int j = 0; j < pptTable.getNumberOfColumns(); j++) {
                TableCell pptCell = pptTable.getCell(i, j);
                String cellData = rowData[j];
                if (cellData != null) {
                    pptCell.setText(cellData);
                    RichTextRun rt =
                            pptCell.getTextRun().getRichTextRuns()[0];
                    rt.setFontName("Arial");
                    rt.setFontSize(10);
                }
            }
        }

        slide.removeShape(shape);

        pptTable.setAllBorders(new Line());

        //HSLF "feature": resizing columns / rows works AFTER the table is added to the slide
        slide.addShape(pptTable);

        int rowHeight = anchor.height/pptTable.getNumberOfRows();
        int colWidth = anchor.width/pptTable.getNumberOfColumns();

        //evenly distribute columns and rows
        for (int i = 0; i < pptTable.getNumberOfRows(); i++) {
            pptTable.setRowHeight(i, rowHeight);
            for (int j = 0; j < pptTable.getNumberOfColumns(); j++) {
                pptTable.setColumnWidth(j, colWidth);
            }
        }

        //set top-left corner of the table
        pptTable.moveTo(anchor.x, anchor.y);

        try {
            ppt.write(new FileOutputStream("PST_out.ppt"));
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }


    }

Summary: Set the table dimensions using Table.setRowHeight and Table.setColumnWidth and then set the Table's top-left corner. Don't use Table.setAnchor.

Yegor