Generování PDF z DOCX šablony
- Rndoom04
- Člen | 75
Dobrý večer vývojáři,
doufám, že jsem téma nezařadil špatně a někoho to nepohorší. :)
Přicházím s dotazem „Jak s docx šablony vygenerovat PDF?“. Našel jsem skvělou knihovnu phpoffice/phpword. Z docx šablony si vytvořím výsledný soubor (nahraním proměnných za texty a přidáním tabulky) – faktura. Soubor je bez chyb. Avšak váznu u generování PDF. PDFko prostě nevypadá tak, jak by mělo – ani zdaleka. Prosím o radu co dělám špatně.
$sablona = WWW_DIR."/tajna/cesta/sablona.docx";
$faktura_location_docx = WWW_DIR."/tajna/cesta/vygenerovano/vydane/faktura.docx";
$faktura_location_pdf = WWW_DIR."/tajna/cesta/vygenerovano/vydane/faktura.pdf";
$pravodni_tabulka = [
'typ_faktury' => "Faktura",
'cislo_faktury' => "1-2021-0001",
'variabilni_symbol' => "123456789",
'datum_vystaveni' => "1.1.2021",
'datum_splatnosti' => "1.2.2021",
'odberatel_jmeno' => "Jane Doe",
'odberatel_adresa' => "Adresa 123, 12345 Město",
'odberatel_stat' => "Česká republika",
'odberatel_ico' => "123 45 678",
'odberatel_dic' => "",
'castka_celkem' => "1.500 Kč",
'castka_uhrazeno_zalohout' => "0.00 Kč",
'castka_zbyva_uhradit' => "1.500 Kč",
'poznamka' => "",
'poznamka_2' => "",
];
copy($sablona,$faktura_location_docx);
// Vytvoř tabulku s produkty
// Vytvoř styly
$table_style = array(
'unit' => \PhpOffice\PhpWord\Style\Table::WIDTH_PERCENT,
'width' => 100 * 50
);
$tabulkaPrvniRadek = array('size' => 7, 'bold' => true);
$tabulkaBunkyStyl = array(
'borderBottomColor' =>'000000',
'borderBottomSize' => 1,
'valign' =>'center',
);
$tabulkaBunkyStylText = array(
'size' => 7,
'bold' => false,
);
// Zarovnání
$cellVCentered = array('valign' => 'center');
$cellHCenter = array(
'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER,
'spaceBefore' => 50,
'spaceAfter' => 50
);
$cellHLeft = array(
'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::LEFT,
'spaceBefore' => 50,
'spaceAfter' => 50
);
$cellHRight = array(
'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::RIGHT,
'spaceBefore' => 50,
'spaceAfter' => 50
);
// Vytvoř element
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord->addTableStyle('produktyTable', $table_style);
$section = $phpWord->addSection();
$table = $section->addTable('produktyTable');
// Přidej tabulce „hlavičku” (první řádek)
$table->addRow();
$table->addCell(5550,$tabulkaBunkyStyl)->addText("Označení zboží, či služby", $tabulkaPrvniRadek, $cellHLeft);
$table->addCell(1000,$tabulkaBunkyStyl)->addText("Počet m. j.", $tabulkaPrvniRadek, $cellHRight);
$table->addCell(1000,$tabulkaBunkyStyl)->addText("Cena za m. j.", $tabulkaPrvniRadek,$cellHRight);
$table->addCell(800,$tabulkaBunkyStyl)->addText("Celkem", $tabulkaPrvniRadek,$cellHRight);
// Přidej jednotlivé produkty
for ($r = 1; $r <= 8; $r++) {
$table->addRow();
$table->addCell(5550,$tabulkaBunkyStyl)->addText("Produkt $r", $tabulkaBunkyStylText, $cellHLeft,);
$table->addCell(1000,$tabulkaBunkyStyl)->addText("1", $tabulkaBunkyStylText, $cellHRight);
$table->addCell(1000,$tabulkaBunkyStyl)->addText("1.500 Kč", $tabulkaBunkyStylText, $cellHRight);
$table->addCell(800,$tabulkaBunkyStyl)->addText("1.500 Kč", $tabulkaBunkyStylText, $cellHRight);
}
// Vytvoř writer pro konverzi XML
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
// Získej všechny XMLv dokumentu
$fullxml = $objWriter->getWriterPart('Document')->write();
// Získej jenom XML tabulky
$tablexml = preg_replace('/^[\s\S]*(<w:tbl\b.*<\/w:tbl>).*/', '$1', $fullxml);
// Otevři dokument s ${table}
$template_document = new \PhpOffice\PhpWord\TemplateProcessor($faktura_location_docx);
// Změn hodnotu tabulky
$template_document->setValue('tabulka_s_produkty', $tablexml);
foreach($pravodni_tabulka as $klic => $nova_hodnota) {
$klic = str_replace(['$','{','}'], ['','',''], $klic);
$template_document->setValue($klic, $nova_hodnota);
}
// Ulož hotovou fakturu do docx
$template_document->saveAs($faktura_location_docx);
// Ulož do PDF
$domPdfPath = realpath(PHPWORD_BASE_DIR . '/../vendor/dompdf/dompdf');
\PhpOffice\PhpWord\Settings::setPdfRendererPath($domPdfPath);
\PhpOffice\PhpWord\Settings::setPdfRendererName('DomPDF');
//Save it
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord , 'PDF');
$xmlWriter->save($faktura_location_pdf);
Přikládám obrázek chyby https://ibb.co/KW58xqx
Budu rád za jakoukoliiv pomoc. :)
Editoval Rndoom04 (18. 12. 2020 20:40)
- dakur
- Člen | 493
@Rndoom04 Ahoj, jednak tady není úplně správné místo – jsi na fóru ke frameworku Nette. Více se to hodí na fórum jakpsatweb.cz, příp. na Stackoverflow, pokud se nebojíš angličtiny (je tam větší komunita).
Ale když už jsi to napsal – z toho, co je na obrázku, mi to nejvíc připadá jako chybějící styly. S tím nástrojem nemám žádné zkušenosti, ale je dost možné, že třeba některé features DOCX formátu prostě neumí (podobně jako Open/LibreOffice). Osobně bych šel klasickou cestou – ořezat výstup na minimum a postupně po kouskách přidávat prvky a každý z nich nejdřív odladit tak, aby dělal/vypadal, jak má. Víc ti asi za sebe nedokážu pomoct. 🙂