PHPOffice / PHPWord

A pure PHP library for reading and writing word processing documents
https://phpoffice.github.io/PHPWord/
Other
7.21k stars 2.69k forks source link

TemplateParser 0.14 creating corrupted Word file. #1242

Open lonnieezell opened 6 years ago

lonnieezell commented 6 years ago

This is a bug report.

I have some simple envelope files that just have placeholders for from and to addresses in them.

The files generate correctly, but when opened give the error: "The file cannot be opened because there are problems with the contents...". It offers to repair the file, which then opens just fine.

Here's the code building the files:

public function build(string $size = 'narrow'): string
    {
        $template = $size == 'narrow'
            ? self::TPL_NARROW
            : self::TPL_TALL;

        $template = resource_path('templates/'. $template);

        $builder = new TemplateProcessor($template);

        // From
        $builder->setValue('fromName', config('company.name'));
        $builder->setValue('fromAddress', config('company.address'));
        $builder->setValue('fromCity', config('company.city'));
        $builder->setValue('fromState', config('company.state'));
        $builder->setValue('fromZipcode', config('company.zipcode'));

        // to
        $builder->setValue('toName', $this->name);
        $builder->setValue('toAddress', $this->address);
        $builder->setValue('toCity', $this->city);
        $builder->setValue('toState', $this->state);
        $builder->setValue('toZipcode', $this->zipcode);

        $path = storage_path('envelopes/'.uniqid('tmd_env_').'.docx');

        $builder->saveAs($path);

        return $path;
    }

The file is then passed to the browser, and cleaned up:

header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file) . "\"");
echo readfile($file);

unlink($file);
exit();

Example file: EnvelopeTemplate_narrow.docx

Context

chancegarcia commented 6 years ago

I'm encountering the same issue with no repair option

troosan commented 6 years ago

@lonnieezell the following works fine for me (run from the samples directory)

$builder = new \PhpOffice\PhpWord\TemplateProcessor('resources/EnvelopeTemplate_narrow.docx');

// From
$builder->setValue('fromName', config('company.name'));
$builder->setValue('fromAddress', config('company.address'));
$builder->setValue('fromCity', config('company.city'));
$builder->setValue('fromState', config('company.state'));
$builder->setValue('fromZipcode', config('company.zipcode'));

// to
$builder->setValue('toName', 'toName');
$builder->setValue('toAddress', '<b>toAddress</b>');
$builder->setValue('toCity', 'toCity');
$builder->setValue('toState', 'toState');
$builder->setValue('toZipcode', 'toZipcode');

$builder->saveAs('results/EnvelopeTemplate_narrow.docx');

function config($string) {
    return $string;
}

Can you make sure the error is not linked to the values that are passed to the template?

lonnieezell commented 6 years ago

Sorry for the delay getting back to you.

The values are very simple, plain text names & addresses.

I've attached a copy of a file that was generated and is throwing the warning if that helps.

Envelop.docx

troosan commented 6 years ago

@lonnieezell Strange indeed, the document opens without warning in LibreOffice. Word is complaining but it doesn't say what about. If you find out let me know :-S

andi98 commented 6 years ago

Did anyone find a solution? I have the same issue, a very simple file with simple values replaced by TemplateProcessor. If I open the file in LibreOffice or macOS Pages it looks fine, but Word 365 says the file is corrupted...

lonnieezell commented 6 years ago

@andi98 Unfortunately, I was not able to look into it any farther. The company decided to go with PDF for that task instead.

tlorens commented 6 years ago

Output escaping Writing documents of some formats, especially XML-based, requires correct output escaping. Without it your document may become broken when you put special characters like ampersand, quotes, and others in it.

Escaping can be performed in two ways: outside of the library by a software developer and inside of the library by built-in mechanism. By default, the built-in mechanism is disabled for backward compatibility with versions prior to v0.13.0. To turn it on set outputEscapingEnabled option to true in your PHPWord configuration file or use the following instruction at runtime:

\PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true);

andi98 commented 6 years ago

@tlorens Thanks for this hint, good to know, but this didn't help out with the error since I was using test documents with just "${test}" in it.

@ all: I just fixed the issue! The problem was that I was using PCLZIP instead of native php-zip. After installing php-zip on my system and removing the setZipClass-line the exported documents open in MS Word without any problem. So it looks like there is a bug with the templating engine and PCLZIP...

echavanon commented 8 months ago

Output escaping Writing documents of some formats, especially XML-based, requires correct output escaping. Without it your document may become broken when you put special characters like ampersand, quotes, and others in it.

Escaping can be performed in two ways: outside of the library by a software developer and inside of the library by built-in mechanism. By default, the built-in mechanism is disabled for backward compatibility with versions prior to v0.13.0. To turn it on set outputEscapingEnabled option to true in your PHPWord configuration file or use the following instruction at runtime:

\PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true);

Should be in the basic documentation or default setting it saved my day !