Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File is corrupted on IIS server #781

Open
eempey opened this issue Apr 14, 2016 · 12 comments
Open

File is corrupted on IIS server #781

eempey opened this issue Apr 14, 2016 · 12 comments

Comments

@eempey
Copy link

eempey commented Apr 14, 2016

I have PHP office integrated in a laravel application. It works when I run it on my xampp localhost, but when I use it on the IIS production server I get "We're sorry, we can't open text.docx because we found a problem with its contents. The file is corrupt and cannot be opened." I can click through two more error pop-ups warning me about "unreadable content" and then open the file. The file looks fine when I do finally get it opened.
The IIS server uses php version 5.6.14, libxml2 Version 2.9.2 with xml reader & writer enabled and Zend Extension 220131226.
Here is the offending code, I pulled the sections out and still the same error so I know it's not my string formatting.
Also possibly relevant is that on both servers the document opens in "Read Mode" instead of "Print Layout". I would prefer it open in Print Layout.

        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $phpWord->getCompatibility()->setOoxmlVersion(15);      

        // Saving the document as Docx file...
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        header("Content-Description: File Transfer");
        header('Content-Disposition: attachment; filename="' . $client->last_name . '"');
        header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
        header('Content-Transfer-Encoding: binary');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Expires: 0');
        $objWriter->save("php:https://output");

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@ericdowell
Copy link

I used php:https://output as such. Not sure if this will help solve your issue. Good luck.

$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord->getCompatibility()->setOoxmlVersion(15);

$section = $phpWord->addSection();
$section->addText( htmlspecialchars( 'Hello World!' ) );

//Headers
$headers = [
    'Content-Description'       => 'File Transfer',
    'Content-Disposition'       => 'attachment; filename="' . $client->last_name . '.docx"',
    'Content-Type'              => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'Content-Transfer-Encoding' => 'binary',
    'Cache-Control'             => 'must-revalidate, post-check=0, pre-check=0',
    'Expires'                   => '0',
];
//Writer
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter( $phpWord, 'Word2007' );
//Start read from output buffer
ob_start();
//Save to output
$objWriter->save( 'php:https://output' );
//Get the file contents from output buffer and clean
$file = ob_get_clean();

return response()->make( $file, 200, $headers );

Also when using version 0.12.* you have to make sure to use htmlspecialchars for all string values that may have html special characters e.g. htmlspecialchars( $value ).

@jaymiethomas
Copy link

I get this issue as well, but using nginx so it's not an IIS-specific thing. I'll try @ericdowell's suggestions and see if that fixes the issue for me.

@troosan
Copy link
Contributor

troosan commented Jan 8, 2018

@jaymiethomas can you share the corrupt document so we can check the content?

@jaymiethomas
Copy link

Thanks, @troosan - I've attached a sample document. Office 2016 (which the customer uses) is saying there is corrupt data in the file.

report - Sample Coal Project.docx

Here's the Laravel controller code which is generating this, in its entirety:


        $header = array('size' => 12, 'bold' => true);
        $columnHeader = array('size' => 9, 'bold' => true);
        $cellContent = array('size' => 9);
        $footnoteHeader = array('size' => 8, 'bold' => true);
        $footnoteText = array('size' => 8);

        $section = $phpWord->addSection();
        $section->addTextBreak(2);
        $section->addText('Background', $header);
        $section->addTextBreak(1);
        $section->addTextBreak(1);
        $section->addTextBreak(2);
        $section->addText('Performance', $header);
        $section->addTextBreak(1);
        $section->addText('The data below demonstrates the performance of the ' . $project->name . ' project by ' . $project->company->name . '. The data has also been benchmarked against internal and aggregated industry data for other projects in the ' . $project->sector->name . ' sector.');
        $section->addTextBreak(2);

        $rows = 1;
        $cols = 7;

        $table = $section->addTable();
        $table->addRow();
        $table->addCell(4000)->addText("Name", $columnHeader);
        $table->addCell(2500)->addText("Sector", $columnHeader);
        $table->addCell(2000)->addText("Size", $columnHeader);
        $table->addCell(2300)->addText("Cost", $columnHeader);
        $table->addCell(2000)->addText("Total Waste", $columnHeader);
        $table->addCell(2000)->addText("Per 100m2", $columnHeader);
        $table->addCell(2000)->addText("Per £100k", $columnHeader);
        $table->addRow();
        $table->addCell(4000)->addText($project->name, $cellContent);
        $table->addCell(2500)->addText($project->sector->name, $cellContent);
        $table->addCell(2000)->addText($project->present()->size, $cellContent);
        $table->addCell(2300)->addText($project->present()->cost, $cellContent);

        $totalWaste = $this->viewHelper->totalWaste($project, $project->wasteRecords->where('record_type', 1));
        $table->addCell(2000)->addText($totalWaste, $cellContent);
        $table->addCell(2000)->addText(number_format($this->viewHelper->calculatePer100m2($totalWaste, $project->size) * 100, 2), $cellContent);
        $table->addCell(2000)->addText(number_format($this->viewHelper->calculatePer100k($totalWaste, $project->cost) * 100, 2), $cellContent);

        $section->addTextBreak(2);
        $section->addText('Performance against other ' . $project->sector->name . ' projects', $header);
        $section->addTextBreak(1);
        $table = $section->addTable();
        $table->addRow();
        $table->addCell(5000)->addText("Source", $columnHeader);
        $table->addCell(2500)->addText("m3 Per 100m2", $columnHeader);
        $table->addCell(2500)->addText("m3 Per £100k", $columnHeader);
        $table->addRow();
        $table->addCell(5000)->addText($project->company->name . " project averages", $cellContent);
        $table->addCell(2500)->addText(number_format($companyBenchmarkResults->per100m2, 2), $cellContent);
        $table->addCell(2500)->addText(number_format($companyBenchmarkResults->per100k, 2), $cellContent);
        $table->addRow();
        $table->addCell(5000)->addText("Aggregated industry project averages", $cellContent);
        $table->addCell(2500)->addText(number_format($industryBenchmarkResults->per100m2, 2), $cellContent);
        $table->addCell(2500)->addText(number_format($industryBenchmarkResults->per100k, 2), $cellContent);
        $section->addTextBreak(2);
        $section->addText('Please note', $footnoteHeader);
        $section->addText('This information has been provided for information purposes only. Whilst we try to ensure that the content is accurate, we cannot be held responsible for any errors or omissions therein, nor for the consequences of these.', $footnoteText);

        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');

        try {
            $objWriter->save(storage_path('report - ' . $project->name . '.docx'));
        } catch (Exception $e) {

        }
        return response()->download(storage_path('report - ' . $project->name . '.docx'));``` 

@troosan
Copy link
Contributor

troosan commented Jan 9, 2018

Have you tried this with the latest PHPWord version? I tried locally and it works fine.

@jaymiethomas
Copy link

I was on v0.13 and just upgraded to v0.14, but I still see the same issue with corrupted file contents. Were you able to open my sample document, @troosan? Also, what are you using to open the documents? I'm using Word 2016 MSO (16.0.8201.2213).

@troosan
Copy link
Contributor

troosan commented Jan 11, 2018

indeed, I cannot open the document, tried with word 2016 (mac) and word 2010 (win), same result.
I could only open it with libreoffice

@jaymiethomas
Copy link

Thanks @troosan. But when you run the code I supplied are you able to open in Word the document that the code generates?

@troosan
Copy link
Contributor

troosan commented Jan 11, 2018

yes, but I had to hard code some values of course. Can you generate a valid document? If not, it's maybe linked to the values inside $project?

@jaymiethomas
Copy link

Thanks, that's a great clue - I'll check it out. It might be that I need to call htmlspecialchars() on the $project contents.

@jaymiethomas
Copy link

I've commented-out all the document content code and have been incrementally commenting it back in to identify the line which breaks the document. Curiously, it's adding the row immediately after adding the table element:

$table = $section->addTable();
$table->addRow();

There's no dynamic content here, but it's that which appears to break the document - I can't think why that would be the case?

@jaymiethomas
Copy link

An update on this: I think I've solved it. The present()->size line was returning <sup> tags which I think was causing the issue. I did have once instance of only using addRow() which caused the document to be unreadable, but I've been unable to produce that.

For anyone reading this in future, check that you're not passing HTML entities into your Word document unencoded. That's currently my best guess as to what's gone wrong here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants