PHPOffice / PHPPresentation

A pure PHP library for reading and writing presentations documents
https://phpoffice.github.io/PHPPresentation
Other
1.3k stars 519 forks source link

Broken ppt file for large presentation #569

Open Scheissy opened 4 years ago

Scheissy commented 4 years ago

Hey guys!

I'm trying to generate really large presentation file with up to 300 slides and I'm running into an issue with broken ppt files. When I'm trying to open the file I am advised that the file is broken and needs to be repaired. After the repair process is done I always get a prompt telling me that some content could not be read and was removed. When I check the now repaired presentation file most of the slides are correct - in terms of content as well as design. Only a few slides - sometimes just one and other times up to five or six - are actually broken. There are two possible ways the affected slides are broken: either the whole slide is a blank page or I get a slide with broken images - only a box with a red cross is shown. In the second case everything else is fine. The text as well as the chart data is correct and displayed well. This behavior happens at random and in different outcomes. Sometime everything is fine and all slides are okay. Sometimes the prompt that some content had to be removed is displayed without the prior request to repair the ppt file. In this case the presentation contains all slides (no blank slides) with the image issue for some slides. Both errors can be combined - so I can receive a presentation file with a blank slide as well as slides with missing images. If I removed all the images from the presentation the issue also happens. The more content I removed from the slides the less likely an error occurred. Without any content the issue did not occur. But as soon as I add one image to the slide the issue returned. While trying to find the error, I noticed that the broken slides had the wrong slide index set. I dumped the value of the getIndex method and noticed that an old index had been issued for the broken slide. I couldn't see any connection between the broken slide and the indexed slide. The old slide was fine and had different data then the broken slide. Which old index was displayed also appeared to me by chance. Knowing this I went back to remove all content from the slides. Even then I could see that there were still slides with the wrong index set. Now I can use this knowledge and remove the new slide if the index does not match the number of total slides. The issue with the index may be stated right after the slide has been created. So the slide is empty and already broken. If I remove that broken slide and create a new slide that works fine in most cases, but not in all of them. A few cases are left where the new slide is also broken. Since I can't remove and create slides forever that's not really a solution. I am using Homestead v10.0.0 with Laravel 6.10.1. I installed the "phpoffice/phppresentation: dev-develop" package. I'm opening the generated file with PowerPoint on Mac. I added a (simplified) code example below. Thank you in advance for your input and your help!!!

$this->phpPresentation = new PhpPresentation();

$this->phpPresentation->getProperties()
                      ->setCreator(static::$config['author'])
                      ->setLastModifiedBy(static::$config['author'])
                      ->setTitle(null)
                      ->setCompany(null);

$this->phpPresentation->removeSlideByIndex(0);

$this->phpPresentation->getLayout()->setDocumentLayout(['cx' => 1280, 'cy' => 720], true)
                      ->setCX(1280, DocumentLayout::UNIT_PIXEL)
                      ->setCY(720, DocumentLayout::UNIT_PIXEL);

for ($i = 0; $i < 300; $i++) {
    $this->currentSlide = $this->phpPresentation->createSlide();

    $slideIndex = $this->phpPresentation->getIndex($this->currentSlide);
    $numberOfSlides = count($this->phpPresentation->getAllSlides());

    if ($slideIndex + 1 != $numberOfSlides) {
        var_dump('slide #'.$numberOfSlides.' is broken');
    }

    $this->shapeRichText = $this->currentSlide->createRichTextShape()
                                              ->setHeight(100)
                                              ->setWidth(100)
                                              ->setOffsetX(50)
                                              ->setOffsetY(50);

    $this->shapeRichText->createTextRun('Test Text '.$i);

    $this->shapeDrawing = $this->currentSlide->createDrawingShape()
                                             ->setPath(PATH_TO_AN_IMAGE.png)
                                             ->setHeight(100)
                                             ->setOffsetX(200)
                                             ->setOffsetY(200);
}
Progi1984 commented 1 week ago

@Scheissy Hi, Could you send me a sample file with error, please, for reproducing the bug ?