Zkušenosti s použitím PdfResponse v Nette 2.0b a PHP 5.3
- mr.mac
- Člen | 87
Na radu nette guru dávám v plen svoji zkušenost s rozchozením PdfResponse v Nette 2.0 a PHP 5.3 (verze mPDF rovněž 5.3).
PdfResponse má být umístěno v app\libs\PdfResponse\
nebo
kdekoli jinde, pak ale musí být cesta umístěna v libsDir – viz ř.
33 PDFResponse.php, kde se uvádí:
$mPDFPath = "%libsDir%/PdfResponse/mpdf/mpdf.php"
.
Jak jsem tedy postupoval?
- Provedl jsem úpravy v PDFResponse.php dle doporučení #98 a #100.
- V prezenteru, ze kterého chci exportovat do PDF jsem přidal akci:
function actionToPdf($id=0) {
//šablona pro export do PDF
$template = $this->createTemplate()->setFile(APP_DIR."/cesta/k/sablone/toPdf.latte");
//data do šablony
$model = new Model;
$item = $model->find($id)->fetch();
$template->item = $item;
$pdf = new PDFResponse($template);
$pdf->documentTitle = "Nadpis: $item->titul";
$pdf->documentAuthor = "Company name";
$pdf->mPDF->OpenPrintDialog();
$this->sendResponse($pdf);
}
3. Šablona toPdf.latte obsahuje toto:
{extends '../@pdf.layout.latte'}
{block #content}
{$item->name}
{$item->adress}
....
4. Šablona @pdf.layout.latte obsahuje html hlavičku a v body odkaz na {content}, např.:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en" />
<meta name="description" content="MyApplication" />
<meta n:ifset="$robots" name="robots" content="{$robots}">
//DŮLEŽITÉ: mPDF standardně používá styl media="print"
<link rel="stylesheet" media="print" href="{$basePath}/css/print.css" type="text/css">
</head>
<body>
<div id="content">
{include #content}
</div>
</body>
</html>
Takže co bylo pro mě nové je to, že jsem nemohl podstrčit jakoukoli
šablonu a myslet si, že cokoli se napoprvé převede do PHP (vč. všech
stylů apod.) – havarovalo mi to na drobných chybách ve stylech a html
kódu s čím si nette (nebo spíše browser) poradilo „samo“, ale mPDF už
ne. Co je DŮLEŽITÉ: mPDF standardně používá styl
media=„print“, jak je uvedeno v kódu výše.
Takže to chtělo pěkně „čistý stůl“ – čistou html hlavičku, svoje
styly v print.css (např. bez duplicit a různých
formátovacích zvěrstev) a ejhle. Výsledek – dokument v PDF vypadá
pěkně (barevně i černobíle) bez zbytečností.
EDIT: Tip pro opakování záhlaví tabulek na nové
stráce: Z dokumentace mPDF jsem vyčetl toto a funguje to: V šabloně
přidat html tagy u definice záhlaví tabulek takto:
<table repeat_header="1"> nebo <thead> nebo <tfoot>
.
Asi pro vás mnohé, kteří s nette pracujete již delší dobu nic
nového, ale možná pro někoho, kdo začíná to k užitku bude.
Díky autorovi, Honzovi Kuchařovi za rady.
Editoval mr.mac (9. 11. 2011 16:08)
- kralik
- Člen | 230
Ahoj,
prosím nevíš mi poradit.
Zkouším generovat PDF a jednoduché „ahoj svete“ je OK, ale pokud generuji ze šablony dostanu
error: Spojení přerušeno, Spojení se serverem bylo v průběhu načítání stránky ukončeno.
pdf ok:
<?php
//v presenteru
..
$template = "<b>ahoj světe!</b>";
$pdf = new \PDFResponse($template);
$this->sendResponse($pdf);
?>
pdf error:
<?php
//v presenteru
..
$template = $this->createTemplate()->setFile(APP_DIR."/GastroModule/templates/Static/pdf.latte");
$pdf = new \PDFResponse($template);
$this->sendResponse($pdf);
?>
obsah PDFResponse.php
<?php
use Nette\Object,
Nette\Application\IPresenterResponse,
Nette\Callback,
Nette\Environment,
Nette\Utils\Strings,
Nette\Templating\Itemplate;
class PdfResponse extends Object implements Nette\Application\IPresenterResponse {
..
?>
Pokud šablonu pdf.latte otevřu bez * $this->sendResponse($pdf);* tak šablona ok
mooc díky
- kralik
- Člen | 230
bohužel jsem v logu nic nenašel.
Obsah logu při pokusu:
<?php
[Wed Dec 21 11:21:36 2011] [notice] Apache/2.2.21 (Win32) PHP/5.3.8 configured -- resuming normal operations
[Wed Dec 21 11:21:36 2011] [notice] Server built: Sep 10 2011 11:34:11
[Wed Dec 21 11:21:36 2011] [notice] Parent: Created child process 3604
[Wed Dec 21 11:21:36 2011] [notice] Child 3604: Child process is running
[Wed Dec 21 11:21:36 2011] [notice] Child 3604: Acquired the start mutex.
[Wed Dec 21 11:21:36 2011] [notice] Child 3604: Starting 64 worker threads.
[Wed Dec 21 11:21:36 2011] [notice] Child 3604: Starting thread to listen on port 80.
[Wed Dec 21 11:21:36 2011] [notice] Child 3604: Starting thread to listen on port 80.
?>
Nic víc
- knedle
- Člen | 34
moje zkušenosti z dneška – tj. NetteFramework-2.0-PHP5.3 – min
1/ upravit PDFResponse.pdf
- již zmiňováno výše, ale pro jistotu:
<?php
...
use Nette\Object,
Nette\Application\IResponse,
Nette\Callback,
Nette\Environment,
Nette\Utils\Strings,
Nette\Templating\Itemplate;
class PdfResponse extends Object implements IResponse {
...
?>
- změna fce send() – teda tohle jediné jsem dělal naslepo, možná je to zbytečné a původní send() funguje – prostě nevím
<?php
...
public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {
...
?>
- uvnitř této fce opravit volání webalize
<?php
...
$this->outputName = Strings::webalize($this->documentTitle).".pdf";
...
?>
- a protože se mi (a už nemám sílu hledat proč) i přes tyto úpravy hlásil ERROR:
Missing item 'libsDir'
na řádku:
<?php
...
$mpdfPath = Environment::expand(self::$mPDFPath);
...
?>
odkomentoval jsem to nastavení natvrdo o 2 řádky výše:
<?php
...
//if(!self::$mPDFPath) {
self::$mPDFPath = dirname(__FILE__)."/mpdf/mpdf.php";
//}
...
?>
2/ presenter pak prakticky shodný s výše uvedeným:
<?php
...
public function renderPdf() {
//šablona pro export do PDF
$template = $this->createTemplate()->setFile(APP_DIR."/templates/Listek/pdf.latte");
//data do šablony
$template->data = $this->section->data;
$pdf = new \PDFResponse($template);
$pdf->documentTitle = "Podací lístek České pošty ... 3tecky.cz";
$pdf->documentAuthor = "@3knedle";
// $pdf->mPDF->OpenPrintDialog();
$this->sendResponse($pdf);
}
...
?>
(teď je to teda render, ale bude to action…)
dále jsem na svém vývojovém localhostu musel zvýšit memory_limit – a to z 128 na 256MB
byl to boj, byl to boj
Editoval knedle (9. 2. 2012 11:03)
- TOMeek
- Člen | 64
Dneska se s generování PDF peru už od rána. Udělal jsem všechny
úpravy, ale zarazím se na chybě Cannot redeclare class mPDF
.
Laděnka mě odkazuje na řádek 58 v mpdf.php. Verzi jsem testoval
5.3 i 5.4 a pokaždé to skončí stejně. Nevíte co stím?
Edit : Došel jsem na to, že tuto chybu to vyhodí když
chci použít latte šablonu. Pokud si $template
naplním prostým
textem, pdf se generuje bez potíží. Když si šablonu vyrenderuju před
uložením do PDF tak se vypíše normálně.
Edit2 : Checkoutnul jsem si aktuální verzi z SVN, podle návodů předělal pro nette2 a PHP 5.3 a už vše jede jak má. Původní PdfResponse u kterého se vyskytovala chyba jsem stáhnul z Gitu
Edit3 : Když už se vtom vrtám, tak jsem zjistil, že v PdfResponse je sice definice na formát papíru (P / L) ale po zadání to nefunguje. Udělal jsem si teda takovou funkcičku
public function pageFormat() {
return ($this->pageOrientaion == "L") ? $this->pageFormat . '-' . $this->pageOrientaion : $this->pageFormat;
}
která mi ověří jestli chci papír na šířku a tím mi vrátí buď A4-L
nebo jen A4. Pak už jen v mPDFExtended
stačí zaměnit
$this->pageFormat
za $this->pageFormat()
a je
hotovo. Třebas to někomu někdy pomůže.
Editoval TOMeek (12. 4. 2012 14:27)
- Tomáš Votruba
- Moderator | 1114
Pokud by se to někomu hodilo (= dělalo velké potíže vlastní rozjetí), podařilo se mi to zprovoznit na Nette 2.0, bez js, který nepoužívám.
Editoval Schmutzka (14. 4. 2012 2:53)
- Tomáš Votruba
- Moderator | 1114
@thorn: Před pár hodinami jsem aktualizoval, tak se
zkus podívat, čekni verzi Nette a stažení mPDF.
S demem se dělat nechci, protože často měním a nechci si
přidávat práci.
Napiš rovnou, co máš za chybu, uvidíme.
Editoval Schmutzka (14. 4. 2012 23:46)
- thorn
- Člen | 14
tak se mi to podarilo rozchodit, ale jen pokud dam ten test(), tak to projde, ale pokud dam save() nebo output(), napriklad:
Presenter:
<?php
use PdfResponse\PdfResponse;
class TstPresenter extends BasePresenter {
public function renderDefault() {
$this->setLayout('layout');
$template = $this->createTemplate()->setFile(APP_DIR . '\templates\tst\pdf.latte');
$pdf = new PDFResponse($template, $this->context);
$pdf->documentTitle = "Testovaci dokument";
//$pdf->test();
$pdf->save(WWW_DIR . "/generated/");
}
}
?>
Pohled:
<?php
{block title}
AIS - test
{/block}
{block content}
<b>Hello!!!</b>
?>
tak dostanu z ladenky:
<?php
Nette\MemberAccessException
Cannot write to an undeclared property PdfResponse\PdfResponse::$generatedFile.
...
$this->onBeforeComplete($mpdf);
$this->generatedFile = $mpdf; // tu se zastavi
return $this->generatedFile;
?>
Netusis, v cem by mohl byt problem? co mi tam chybi ci tak?
EDIT: verze nette 2.0.3, mPDF je to, co mas v GITu, verze 5.3
EDIT2: tak jsem si s tim chvilku hral, zmenil sem akorat, ze misto
$this->generatedFile vracim rovnou $mpdf, vlastne moc nechapu, proc
generateFile tam je, pak jsem zakomentoval ten if s $this->generatedFile, to
byl jeden problem, pak jsem moc nechapal tomu, ze file_put_contents nevytvori
automaticky novou slozku, tak jsem ji teda vytvoril natvrdo a uz to fici jak ma,
diky, za tu upravu
Editoval thorn (16. 4. 2012 0:30)