PHPOffice / PHPExcel

ARCHIVED
Other
11.46k stars 4.19k forks source link

Fatal PHP error when graphics relationship file (*.rels) is not present. #1308

Open joseph-sabido opened 7 years ago

joseph-sabido commented 7 years ago

Calling $phpexcel_reader->load() on a Excel2007 file fails with the following errors:

Message: Trying to get property of non-object
Filename: \vendor\phpoffice\phpexcel\Classes\PHPExcel\Reader\Excel2007.php
Line Number: 1384

Message: Invalid argument supplied for foreach()
Filename: \vendor\phpoffice\phpexcel\Classes\PHPExcel\Reader\Excel2007.php
Line Number: 1384

Message: Undefined offset: 0
Filename: \vendor\phpoffice\phpexcel\Classes\PHPExcel\Reader\Excel2007.php
Line Number: 1400

Upon investigating it looks like the XLSM file is lacking some of the .rels files, which is causing the crash. The crash is avoided if the following code (lines 1384-1388 in Excel2007.php) is wrapped in IF statements validating the $relsVML variable:

Before:

foreach ($relsVML->Relationship as $ele) {
    if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") {
        $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]);
    }
}

After:

if($relsVML){
    foreach ($relsVML->Relationship as $ele) {
        if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") {
            $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]);
        }
    }
}

Also, the code in lines 1400-1418 needs to be wrapped in a validation:

Before:

$imageData = $imageData[$idx];

$imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office');
$style = self::toCSSArray( (string)$shape['style'] );

$hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing();
if (isset($imageData['title'])) {
$hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] );
}

$hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false);
$hfImages[ (string)$shape['id'] ]->setResizeProportional(false);
$hfImages[ (string)$shape['id'] ]->setWidth($style['width']);
$hfImages[ (string)$shape['id'] ]->setHeight($style['height']);
if (isset($style['margin-left'])) {
$hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']);
}
$hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']);
$hfImages[ (string)$shape['id'] ]->setResizeProportional(true);

After:

if(isset($imageData[$idx])){
    $imageData = $imageData[$idx];

    $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office');
    $style = self::toCSSArray( (string)$shape['style'] );

    $hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing();
    if (isset($imageData['title'])) {
    $hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] );
    }

    $hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false);
    $hfImages[ (string)$shape['id'] ]->setResizeProportional(false);
    $hfImages[ (string)$shape['id'] ]->setWidth($style['width']);
    $hfImages[ (string)$shape['id'] ]->setHeight($style['height']);
    if (isset($style['margin-left'])) {
    $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']);
    }
    $hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']);
    $hfImages[ (string)$shape['id'] ]->setResizeProportional(true);
}
squatto commented 6 years ago

I'm having this exact same issue. I've had no problems reading files with images previously, and now I'm getting these errors.

squatto commented 6 years ago

On one of my worksheets, in Excel I went to "View > Header and Footer..." and displayed the headers/footers. The header had an image in it. When I removed the image this error went away.