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

Cannot save a word document as PDF #2426

Open
RosiersRobin opened this issue Jul 23, 2023 · 4 comments
Open

Cannot save a word document as PDF #2426

RosiersRobin opened this issue Jul 23, 2023 · 4 comments

Comments

@RosiersRobin
Copy link

Describe the Bug

When trying to modify a word document (has a header and footer text in it) then the modification works perfectly. However, the word document needs to be a PDF. When I try to save it as PDF, I get Cannot add Title in Header.

Steps to Reproduce

Please provide a code sample that reproduces the issue.

<?php
require __DIR__ . '/vendor/autoload.php';

$templateFile = storage_path('app/wordDocument.docx');
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor($templateFile);

// set word values
$templateProcessor->setValue('{teamnr}', '123');

$outputFileDocx = storage_path('app/output_files/wordDocument.docx');
$templateProcessor->saveAs($outputFileDocx);

// load the word document again
$outputFilePdf = storage_path('app/output_files/pdf_file.pdf');
$phpWord = \PhpOffice\PhpWord\IOFactory::load($outputFileDocx);

//Save it into PDF
$PDFWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord,'PDF');
$PDFWriter->save($outputFilePdf);

Expected Behavior

I expect the word to be saved as a pdf file.

Current Behavior

Exception gets throwed:

 BadMethodCallException

  Cannot add Title in Header.

  at vendor\phpoffice\phpword\src\PhpWord\Element\AbstractContainer.php:270
    266267// Check if a method is valid for current container
    268if (isset($validContainers[$method])) {
    269if (!in_array($this->container, $validContainers[$method])) {
  ➜ 270throw new BadMethodCallException("Cannot add {$method} in {$this->container}.");
    271▕             }
    272▕         }
    273274// Check if a method is valid for current container, located in other container

  1   vendor\phpoffice\phpword\src\PhpWord\Element\AbstractContainer.php:135
      PhpOffice\PhpWord\Element\AbstractContainer::checkValidity("Title")

  2   vendor\phpoffice\phpword\src\PhpWord\Element\AbstractContainer.php:116
      PhpOffice\PhpWord\Element\AbstractContainer::addElement("Title", Object(PhpOffice\PhpWord\Element\TextRun), "1")

Context

Please fill in your environment information:

  • PHP Version: 8.2.8
  • PHPWord Version: ^1.1
  • windows 10 pro
  • Laravel 10
@allestaire
Copy link

You have to set the reader first, its either MPDF or DomPDF

\PhpOffice\PhpWord\Settings::setPdfRendererName(\PhpOffice\PhpWord\Settings::PDF_RENDERER_MPDF);
$phpWord = \PhpOffice\PhpWord\IOFactory::load(storage_path('generated.docx'),);
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'PDF');
$xmlWriter->save(storage_path('generated.pdf'));

@RosiersRobin
Copy link
Author

@allestaire
I've done as you suggested. When I don't replace anything, it works just fine. However, when I replace only 1 thing, it breaks.

to even better simulate, I have attached the word document it should change and save as pdf here: https://filetransfer.io/data-package/WNmNVR95#link

the full code I currently use:

<?php

use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\TemplateProcessor;

$domPdfPath = base_path('vendor/dompdf/dompdf');
    Settings::setPdfRendererPath($domPdfPath);
    Settings::setPdfRendererName('DomPDF');

    $templateFile = storage_path('app/documents/source_files/Acceptatiebrief.docx');
    $templateProcessor = new TemplateProcessor($templateFile);
    $templateProcessor->setValue('{teamnr}', '123');
    $templateProcessor->setValue('{strt_hr}', '18:31');
    $templateProcessor->setValue('{pilot_name}', 'DOE John');
    $templateProcessor->setValue('{pilot_license}', 'W123456R');
    $templateProcessor->setValue('{pilot_club}', 'Amazing club');
    $templateProcessor->setValue('{pilot_tel}', '+333333333');
    $templateProcessor->setValue('{copilot_name}', 'DOEDETTE Johanna');
    $templateProcessor->setValue('{copilot_license}', 'A65412D');
    $templateProcessor->setValue('{copilot_club}', 'Woops');
    $templateProcessor->setValue('{copilot_tel}', '');
    
    $outputFileDocx = storage_path('app/documents/output_files/Acceptatiebrief_test.docx');
    $templateProcessor->saveAs($outputFileDocx);

    \PhpOffice\PhpWord\Settings::setPdfRendererName(\PhpOffice\PhpWord\Settings::PDF_RENDERER_DOMPDF);
    $phpWord = \PhpOffice\PhpWord\IOFactory::load($outputFileDocx);
    $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'PDF');
    $xmlWriter->save(storage_path('app/documents/output_files/Acceptatiebrief_test.pdf'));

Any ideas on what I'm doing wrong?

@allestaire
Copy link

allestaire commented Oct 13, 2023

Seems like there is a problem with the docx format,
Like when there are spaces or empty value, the other line will merge to top
You should check first on how those elements being placed

Also can you share the original docx?

then converting docx to pdf is not totally reliable, as I tested it, it loses styles, and there are only I guess 80% of accuracy
The problem might not be the template process but probabbly how the element is placed

@RosiersRobin
Copy link
Author

@allestaire https://filetransfer.io/data-package/WNmNVR95#link this url contains the original docx file (with just the {replace} tags used.

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

No branches or pull requests

2 participants