Bug 45633 - PPT Table problem
Summary: PPT Table problem
Status: RESOLVED WONTFIX
Alias: None
Product: POI
Classification: Unclassified
Component: HSLF (show other bugs)
Version: unspecified
Hardware: PC Linux
: P1 normal (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-08-14 06:56 UTC by Constantin
Modified: 2008-08-18 11:24 UTC (History)
0 users



Attachments
PPT file (259.00 KB, application/octet-stream)
2008-08-14 06:56 UTC, Constantin
Details
Result file screenshot (133.51 KB, image/jpeg)
2008-08-14 07:01 UTC, Constantin
Details

Note You need to log in before you can comment on or make changes to this bug.
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