Skip to content

Cannot update a docx containing an image #1212

Open
@wadmiraal

Description

@wadmiraal

I need to generate a pretty large Word document, with lots of data from a database.

Instead of fetching all the data in one go, and risking a timeout, I fetch a set number of elements at a time, and process the document in a batch.

A very crude simplification would look like this:

$filepath = '/absolute/path/to/file.docx';

// Initial batch run:
$phpword = new \PhpOffice\PhpWord\PhpWord();
$phpword->getSettings()->setUpdateFields(true);
// Set some settings...
$section = $phpword->addSection();
// Add text, images, etc;
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

// Subsequent batch runs:
$phpword = \PhpOffice\PhpWord\IOFactory::load($filepath);
$phpword->getSettings()->setUpdateFields(true);
// Set some settings...
$section = $phpword->addSection();
// Add text, images, etc;
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

So far so good.

However (and I've been banging my head for hours now), if at one point I add an image, I can no longer update the document. It will throw an exception: Could not close zip file, and PHP throws the following warning: ZipArchive::close(): Invalid or uninitialized Zip object.

If I use PeclZip, it will not throw any error, but the file won't be readable.

Expected Behavior

I would expect a document to be loaded correctly, and then be save-able again. This is the case as long as no image is added.

Current Behavior

If the document contains an image, it can be opened, but not updated.

I tried copying the file prior to opening it, renaming it, to no avail. I checked file permissions, but it doesn't seem to matter. I updated the user:group of the webserver to make certain it wasn't that either: no success.

Failure Information

\PhpOffice\PhpWord\Exception\Exception thrown: Could not close zip file (in \PhpOffice\PhpWord\Shared\ZipArchive::close())
PHP warning: ZipArchive::close(): Invalid or uninitialized Zip object

How to Reproduce

Running this code triggers the error (I'm on the latest dev commit):

$filepath = '/absolute/path/to/file.docx';
$image = '/absolute/path/to/image.png';

$phpword = new \PhpOffice\PhpWord\PhpWord();
$phpword->getSettings()->setUpdateFields(true);
$phpword->setDefaultFontName('Verdana');
$phpword->setDefaultFontSize(9);
$section = $phpword->addSection();
$section->addImage($image);
$section->addTextBreak();
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

sleep(5); // This is not needed, but just to make absolutely sure 

$phpword = \PhpOffice\PhpWord\IOFactory::load($filepath);
$phpword->getSettings()->setUpdateFields(true);
$phpword->setDefaultFontName('Verdana');
$phpword->setDefaultFontSize(9);
$section = $phpword->addSection();
$section->addText('Lorem ipsum');
$section->addTextBreak();
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

Context

  • PHP version: 5.6.31 and 7.1.12
  • PHPWord version: master-dev

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions