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

Saving to pdf error #407

Open
ghost opened this issue Nov 6, 2014 · 22 comments
Open

Saving to pdf error #407

ghost opened this issue Nov 6, 2014 · 22 comments

Comments

@ghost
Copy link

ghost commented Nov 6, 2014

Hi,
I'm creating a docx successfully.
However right after generating it I cannot create a pdf version with TCPDF.

Here's my code:

$finalname = 'test'.uniqid(true);
$finalnamedocx = $finalname.'.docx';

/////////////////// SAVE AS DOCX ////////////////////
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($PHPWord, 'Word2007');
$objWriter->save($finalnamedocx); // so far so good

/////////////////// SAVE AS PDF ////////////////////
\PhpOffice\PhpWord\Settings::setPdfRendererPath('tcpdf_min'); // that's where it is
\PhpOffice\PhpWord\Settings::setPdfRendererName('TCPDF');
// reload it
$PHPWord = \PhpOffice\PhpWord\IOFactory::load($finalnamedocx);
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($PHPWord , 'PDF');
$xmlWriter->save($finalname.'.pdf');

And here's my error stack:

PHP Fatal error:  Uncaught exception 'PhpOffice\PhpWord\Exception\InvalidImageException' in /home/hello/public_html/world/PHPWord-master/src/PhpWord/Element/Image.php:371
Stack trace:
#0 /home/hello/public_html/world/PHPWord-master/src/PhpWord/Element/Image.php(129): PhpOffice\PhpWord\Element\Image->checkImage('zip:https://test1...')
#1 [internal function]: PhpOffice\PhpWord\Element\Image->__construct('zip:https://test1...')
#2 /home/hello/public_html/world/PHPWord-master/src/PhpWord/Element/AbstractContainer.php(138): ReflectionClass->newInstanceArgs(Array)
#3 [internal function]: PhpOffice\PhpWord\Element\AbstractContainer->addElement('Image', 'zip:https://test1...')
#4 /home/hello/public_html/world/PHPWord-master/src/PhpWord/Element/AbstractContainer.php(101): call_user_func_array(Array, Array)
#5 /home/hello/public_html/world/PHPWord-master/src/PhpWord/Reader/Word2007/AbstractPart.php(222): PhpOffice\PhpWord\Element\AbstractContainer->__call('addImage', Array)
#6 /home/hello/public_html/worl in /home/hello/public_html/world/PHPWord-master/src/PhpWord/Element/Image.php on line 371

It looks like it's trying to access images at zip:https://filename??


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

@franzholz
Copy link

Could you try it also with the Develop branch and by using dompdf?
Give a link to the DOCX file which causes the error.

@ghost
Copy link
Author

ghost commented Nov 6, 2014

Thanks franzholz
Now I've got this

\PhpOffice\PhpWord\Settings::setPdfRendererPath('dompdf-master');
\PhpOffice\PhpWord\Settings::setPdfRendererName('DOMPDF');
// reload it
$PHPWord = \PhpOffice\PhpWord\IOFactory::load($finalnamedocx);
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($PHPWord , 'PDF');
$xmlWriter->save($finalname.'.pdf');

And funnily it throws exactly the same error.
I've got a feeling I'm not calling setPdfRendererPath the right way. I've uploaded the whole dompdf-master folder via ftp to the root of my app, which is also where the script is run from

@franzholz
Copy link

Can you show the exact error message from the PHPWord Develop branch?
Check the DOCX word file for the exact reason. E.g. you remove parts of your document until it works.

@ghost
Copy link
Author

ghost commented Nov 6, 2014

Sure! Here it is:

PHP Fatal error:  Uncaught exception 'PhpOffice\PhpWord\Exception\InvalidImageException' in /home/hello/public_html/world/PHPWord-develop/src/PhpWord/Element/Image.php:383
Stack trace:
#0 /home/hello/public_html/world/PHPWord-develop/src/PhpWord/Element/Image.php(138): PhpOffice\PhpWord\Element\Image->checkImage('zip:https://test1...')
#1 [internal function]: PhpOffice\PhpWord\Element\Image->__construct('zip:https://test1...')
#2 /home/hello/public_html/world/PHPWord-develop/src/PhpWord/Element/AbstractContainer.php(145): ReflectionClass->newInstanceArgs(Array)
#3 [internal function]: PhpOffice\PhpWord\Element\AbstractContainer->addElement('Image', 'zip:https://test1...')
#4 /home/hello/public_html/world/PHPWord-develop/src/PhpWord/Element/AbstractContainer.php(112): call_user_func_array(Array, Array)
#5 /home/hello/public_html/world/PHPWord-develop/src/PhpWord/Reader/Word2007/AbstractPart.php(225): PhpOffice\PhpWord\Element\AbstractContainer->__call('addImage', Array)
#6 /home/hello/public_html in /home/hello/public_html/world/PHPWord-develop/src/PhpWord/Element/Image.php on line 383

@franzholz
Copy link

The name 'zip:https://test1...' is confusing. This probably is no image file. What is the name of your DOCX file? Can you show us the file you have used?

@ghost
Copy link
Author

ghost commented Nov 6, 2014

Thanks for your help Franz.

Yes, "text1..." is the name of the docx file I generate 3 lines up.

I cannot attach the resulting file (it only accepts PNG GIF or JPG). But I've ony made it a few lines long (add image, add table and generate) I've cut it to this: Without the following line it works:

$section->addImage('/home/hello/public_html/world/assets/img/frontpage1.jpg',array('width'=>100));

Have also tried

$section->addImage('assets/img/frontpage1.jpg',array('width'=>100)); //relative
$section->addImage('/world/assets/img/frontpage1.jpg',array('width'=>100)); // from the root
$section->addImage('home/hello/public_html/world/assets/img/frontpage1.jpg',array('width'=>100));

None work, only the last one (starts without a "/") says PhpOffice\PhpWord\Element\Image->checkImage('home/hello/p...') instead of checkImage('zip:https://test15...')

@franzholz
Copy link

Could you write me the full sequence how you generate your DOCX file?

$phpWord = new \PhpOffice\PhpWord\PhpWord();
    // missing lines
$finalname = 'test'.uniqid(true);
$finalnamedocx = $finalname.'.docx';

/////////////////// SAVE AS DOCX ////////////////////
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$objWriter->save($finalnamedocx); // so far so good

@ghost
Copy link
Author

ghost commented Nov 7, 2014

Sure: in the simplified version (which doesn't work either with that addImage line) it goes:

<?php
require_once 'PHPWord-0.11.1/src/PhpWord/Autoloader.php';
\PhpOffice\PhpWord\Autoloader::register();

require_once 'simplehtmldom/simple_html_dom.php'; 
require_once 'htmltodocx_converter/h2d_htmlconverter.php';

$PHPWord = new \PhpOffice\PhpWord\PhpWord();

$styleTable1 = array('width' => 566, 'cellMargin' => 50);
$PHPWord->addTableStyle('mytstyle', $styleTable1);

$section = $PHPWord->createSection(array('marginLeft'=>900, 'marginRight'=>900, 'marginTop'=>2500, 'marginBottom'=>900));

$section->addImage('assets/img/frontpage1.jpg');
$section->addTextBreak(1);
$table = $section->addTable('mytstyle');
$table->addRow(900);

$cell = $table->addCell(2000);
$cell->addText("Document No. ");
$cell->addText("Conducted on:");
$cell->addText("test1");
$cell->addText("Completed on");
$cell->addText("test2");

////////////////////////////////////////////////////////////////////////////////////
$finalname = 'test'.uniqid(true);
$finalnamedocx = $finalname.'.docx';
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($PHPWord, 'Word2007');
$objWriter->save($finalnamedocx);

// use either tcpdf
\PhpOffice\PhpWord\Settings::setPdfRendererPath('tcpdf_min');
\PhpOffice\PhpWord\Settings::setPdfRendererName('TCPDF');

// or dompdf
//\PhpOffice\PhpWord\Settings::setPdfRendererPath('dompdf');
//\PhpOffice\PhpWord\Settings::setPdfRendererName('DomPDF');

// reload it
$PHPWord = \PhpOffice\PhpWord\IOFactory::load($finalname.'.docx');
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($PHPWord , 'PDF');
$xmlWriter->save($finalname.'.pdf'); // saved at the root
////////////////////////////////////////////////////

I've got the same issue exactly with tcpdf and dompdf so I think it's on the phpword side of things

@franzholz
Copy link

I have tried your steps. And it passes the error reported by you.
I have used another file name:

 $finalname = 'test-issue-407';

The folder assets must contain a subfolder img and this subfolder must contain the file frontpage1.jpg.

 $section->addImage('assets/img/frontpage1.jpg');

Image.php:  385
   checkImage $imageData

0   300
1   429
2   2
3   width="300" height="429"
bits    8
channels    3
mime    image/jpeg

checkImage $source:

  assets/img/frontpage1.jpg

I do not get the strange "zip:https://test1..." file. You probably use another configuration. I do not know how you managed to get the ZIP file here instead of the image file name.

@ghost
Copy link
Author

ghost commented Nov 7, 2014

:(
The image does exist (checking if file exists, and that type is jpg from the script)
Sorry I don't understand where/how you call the private function checkImage $imageData ?

Is there anything to configure elsewhere??
In phpword/Settings.php I've got

 const ZIPARCHIVE = 'ZipArchive';
    const PCLZIP     = 'PclZip';
    const OLD_LIB    = 'PhpOffice\\PhpWord\\Shared\\ZipArchive'; // @deprecated 0.11

    const PDF_RENDERER_DOMPDF = 'DomPDF';
    const PDF_RENDERER_TCPDF  = 'TCPDF';
    const PDF_RENDERER_MPDF   = 'MPDF';

It's so frustrating! I'd like to avoid having to redevelop a parallel code only for pdf!

@franzholz
Copy link

The function addImage in your code calls AbstractContainer.php function __call($function, $args). This calls function addElement and it calls $element = $reflection->newInstanceArgs($elementArgs);. This uses the ReflectionClass around PhpOffice\PhpWord\Element\Image. The ReflectionClass then creates a new instance the Image class and calls its constructor __construct which is on the file Image.php. There you have the call of $this->checkImage($source);.
Therefore the $source must always be the filename given to your call of the function addImage. Maybe there is another call to this on a later stage.

On my environment I cannot proceed to the creation of the ZIP archive of the file DOCX. I do not know why. Your save call will come to the file ZipArchive.php and it has the $zipFunction named addFile .
$args:

0   assets/img/frontpage1.jpg
1   word/media/section_image1.jpg

This function never returns. It hangs: $result = @call_user_func_array(array($zipObject, $zipFunction), $args);. Can it be that this call to PHP ZipArchive works in your environment?

I have found out, that there is a bug in PHP ZipArchive addFile
https://bugs.mageia.org/show_bug.cgi?id=13820

It might take some time until I can continue.

@ghost
Copy link
Author

ghost commented Nov 9, 2014

No idea, not sure how I could test that...

@ghost
Copy link
Author

ghost commented Nov 13, 2014

I may know what's wrong:
The images I add are not embedded in the docx file. If I open it without an internet connection all the images are gone.
The pdf converter probably needs embedded images.
How you I add inages to the docx file as embeds, not as mere url references?

@ghost
Copy link
Author

ghost commented Nov 14, 2014

Hi Franz,
Do you think the link you refer to
https://bugs.mageia.org/show_bug.cgi?id=13820
is the bug I'm facing?

@franzholz
Copy link

The images are always read in as data in base64 format. Have a look into the file src/PhpWord/Element/Image.php .
getImageStringData

Yes, maybe you are facing the same PHP internal error with ZIPArchive. This is because your image data cannot be read from the archive DOCX file. If PHP ZipArchive's addFile function did fail, then you wiil fail to read it again. You should compare your PHP version with the PHP bug tracker.

@emepetres
Copy link

Hi guys, I'm having exactly the same problem as underfrog. The PHP version I'm using is 5.6.8 and I tried with both master and develop branches of DomPDF and PHPWord, without any luck.

Has anyone resolved this before?

@ghost
Copy link
Author

ghost commented May 8, 2015

Hi emepetres,
My advice would be forget it. I know it sounds negative but it is simply not doable with this library.
4 months ago I spent days trying, and got several other highly skilled developers on the case, none succeeded. I ended up re-building my word document in tcpdf, which is a lot of work for a result that's not optimal since it's very hard to get the same result (different functionalities).

@emepetres
Copy link

Hi underfrog,
I was hoping your advice could not be the most reasonable way to overcome this issue, but after trying all day long I have to agree with you lol.

I'm thinking I'm going to give a try to html2pdf and see what it can do. Thank you for your answer.

@rajeshbabu54
Copy link

Hello everyone,
I want to add some images and text to existing docx in phpword.I tried with the following code but it is not showing correct.

include_once 'Sample_Header.php';
// New Word document
$name = basename(FILE, '.php');
$source = DIR . "/resources/{$name}.docx";
//$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord1 = \PhpOffice\PhpWord\IOFactory::load($source);
$document = $phpWord1->loadTemplate($source);
$document->saveAs('temp.docx');
$phpWord = \PhpOffice\PhpWord\IOFactory::load('temp.docx');
$section = $phpWord->addSection();
$section->addText(htmlspecialchars('Local image without any styles:'));
$section->addImage('resources/_mars.jpg');
$section->addTextBreak(2);
$source = 'http:https://php.net/images/logos/php-med-trans-light.gif';
$section->addText(htmlspecialchars("Remote image from: {$source}"));
$section->addImage($source);
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord , 'Word2007');
$xmlWriter->save('result1234566.docx');

Please send me the code. Please help me out from this problem

Thank you

Rajesh babu

@yjrowe
Copy link

yjrowe commented Mar 19, 2019

public function office_to_pdf($FilePath, $FilePathPdf)
{
$rendererLibraryPath = ROOT_PATH . 'vendor/phpoffice/phpword/src/PhpWord/Writer/PDF';
\PhpOffice\PhpWord\Settings::setPdfRendererPath($rendererLibraryPath);
\PhpOffice\PhpWord\Settings::setPdfRendererName('DomPDF');

    //Load temp file
    $phpWord = \PhpOffice\PhpWord\IOFactory::load($FilePath);

    //Save it
    $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord , 'PDF');
    $xmlWriter->save($FilePathPdf);
}

the pdf is not same as docx and chartset is wrong, how to solve this problem? thanks in advance.

@tljafar
Copy link

tljafar commented Oct 30, 2020

That's worked for me

(new \PhpOffice\PhpWord\Writer\PDF\DomPDF($phpWord))->save('helloWorld.pdf');

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If this is still an issue for you, please try to help by debugging it further and sharing your results.
Thank you for your contributions.

@github-actions github-actions bot added the Stale label Nov 18, 2022
@Progi1984 Progi1984 removed the Stale label Nov 18, 2022
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

6 participants