PHPOffice / PHPWord

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

templateProcessor saveAs is generate corrupt file #2083

Open rmohammad25 opened 3 years ago

rmohammad25 commented 3 years ago

Describe the Bug

When i try to load the template docx thru TemplateProcessor and save as a new file , it will generate a corrupt file , like this

image

All i did is just to save it to new file.

Steps to Reproduce

Please provide a code sample that reproduces the issue.

Test Case 1

$document = new \PhpOffice\PhpWord\TemplateProcessor('old_file.docx');
$document->saveAs('new_file.docx');

Test Case 2

$document = new \PhpOffice\PhpWord\TemplateProcessor('old_file.docx');
$document->setValue('name', 'phpword');
$document->saveAs('new_file.docx');

Expected Behavior

Ive try a bunch of fixes like :

mattimatti commented 2 years ago

FYI, I have the same issue

fixed not using the saveAs function patched for windows

    $this->getTemplate()->saveAs($file_name);

to this that uses rename

    $temp_filename = $this->getTemplate()->save();

    if (file_exists($file_name)) {
        unlink($file_name);
    }

    rename($temp_filename, $file_name);
    unlink($temp_filename);
rmohammad25 commented 2 years ago

@mattimatti i already found out the problem. Its because some of the content of the docx cannot be translated, for example; a very complex table with lots of layout and etc. If you can test a very simple docx vs a complex docx ( with image) you can see the difference

LeftToast commented 11 months ago

I have the same problem using the Template Processor.

Settings::loadConfig(); Settings::setZipClass(Settings::PCLZIP); Settings::setOutputEscapingEnabled(true); Settings::setCompatibility(false);

$newpost = array_map_recursive('htmlspecialchars', $_POST);
$doc = new TemplateProcessor(BASE_URL . "/forms/lease_template.docx");

$fname = $newpost['element_1_1'];
$lname = $newpost['element_1_2'];
$emailAddr1 = filter_var($newpost["element_14"], FILTER_VALIDATE_EMAIL);
$telephone = formatPhone($newpost["element_2"]);
$govID = preg_replace("/[^A-Za-z0-9 ]/", '', $newpost["element_3"]);
$T1FullName = $newpost["element_1_1"] . " " . $newpost["element_1_2"];

$t1Details = array(
        'Tn1FName' => $fname,
        'Tn1LName' => $lname,
        'Tn1Phone' => $telephone,
        'Tn1Email' => $emailAddr1,
        'Tn1IDNum' => $govID,
        'Tn1IDType' => 'Drivers',
        'T1Sig' => '[s:tenant1]',
        'T1SigDate' => '[d:tenant1]'
 );
$doc->setValues($t1Details);

$docID = date('Y-m-d') . '_' . substr(sha1(rand()), 0, 6);
$NameOfFile = "ResidentialLease_" . $prop . '_' . $suiteNum . '_' . $T1FullName . '_' . $docID . '.docx';

// write new MS Word and PDF documents
$input_file = BASE_URL . '/forms/' . $NameOfFile;
$doc->saveAs($input_file);

The saved document is corrupted. When I download it from the hosted server, Word says it's corrupted, when repaired, it has none of the field tags replaced.

Yevgeniy-B commented 11 months ago

I faced similar problem when PhpWord saved files, but they were corrupted. As I used PhpWord for single operation [ just $template->setValues ($data_array) and $template->saveAs($full_save_path);] it took some time to realize that corrupted files contained ampersand (&) in the $data_array. I've updated PhPOffice via Composer and checked the updated documentation for the library: https://phpoffice.github.io/PHPWord/usage/introduction.html

There is a dedicated section to the discussed problem: "Output escaping", which says: "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. ... 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: <?php \PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true); ?>"

After I enabled built-in PhpWord output escaping my problem seems to be solved. Hope it helps !

LeftToast commented 11 months ago

It seems the the problem is related to the ZIP library. When I comment out the following:

//Settings::setZipClass(Settings::PCLZIP);

It now works. This doesn't explain why it worked for 14 months using the recommended setting, and stopped suddenly on October 4, but it works now without this setting.

lordkyle0 commented 5 months ago

Anyone can help ?

bunglegrind commented 2 months ago

It seems the the problem is related to the ZIP library. When I comment out the following:

//Settings::setZipClass(Settings::PCLZIP);

It now works. This doesn't explain why it worked for 14 months using the recommended setting, and stopped suddenly on October 4, but it works now without this setting.

see https://github.com/PHPOffice/PHPWord/issues/2613#issuecomment-2213998361