Jak renderovat komponentu do PDF?
- crempa
- Člen | 198
Ahoj,
chtel bych se zeptat jak by jste resili pripad kdy mate komponentu, rekneme napr. klasickou tabulku ktera se muze renderovat jednak jako soucast stranky do HTML, ale je potreba i moznost renderovat komponentu do PDF. Nejlepe tak ze po prijeti signalu „renderuj se do PDF“ probehne vse uplne normalne a teprve v miste renderovani se obsah sablon(y) misto poslani na vystup zachyti do promenne a posle nejake PDF tride ke zpracovani.
Tohle vsechno je OK, jak ale nejak systemove hezky zabranit aby se pred a po generovanim PDF vypisoval vystup ze zbytku stranky, tj. komponenty pred onou renderovanou, menu atd.
Zatim to delam tak ze v base presenteru zjistim zda je poslan onen signal (lhostejno na jakou komponentu) a pokud ano tak zapnu output buffering, ten pak tesne pred vysupem do PDF vypnu a zahodim nacez po odeslani PDF nasleduje osklivej exit…
Zmineny postup funguje, ale vubec se me nelibi, takze se ptam, zda s timto nemate nekdo zkusenot a jak to pripadne resit nejak lepe…
Diky !
- Ondřej Mirtes
- Člen | 1536
U komponent nevím (u nich metody render jednoduše znamenají „echo“ nějakého HTML kódu, protože jsou obvykle použity jako „widgety“ – součásti HTML kódu celé stránky), ale pro samotný Presenter by se hodilo napsat třídu implementující IPresenterResponse, např. PdfResponse (jak taková třída cca vypadá, můžeš se podívat na zdroják DownloadResponse, která by podle vstupu vytvořila PDF soubor a ten by nabídla ke stáhnutí. V Presenteru bys akorát v té handle* metodě napsal něco takovéhleho:
$this->terminate(new PdfResponse($text, $filename));
A bylo by to :)
- crempa
- Člen | 198
Jasne, takhle v ramci presenteru proc ne, ale vezmi si treba pripad te tabulky (nebo datagridu at jsem presnejsi), najdu si tam pomoci filtru strankovani atd. potrebnej soubor dat a ted chci ten aktualni stav promitnout do toho PDF tj. jen ten vystup presmerovat misto do HTML do te PDF tridy.
Vicemene jde o podobnou situaci jako je ajax, vse probehne normalne jako u klasickeho dotazu jen se neodesle vystup, resp. se nahradi tim PDFkem.
Asi to tedy zatim necham tak jak to je, teoreticky by asi slo vytvorit komponentu manualne a ne tovarnickou a nasledne by se to resilo tak jak rikas, ale problem je ze i tak ji nezustanou perzistentni parametry (filtr, razeni apod.)
Editoval crempa (23. 2. 2010 11:59)
- Ola
- Člen | 385
Pokud bys to udělal jako signál, máš dost času přesměrovat na nějaký download presenter s parametrem file, který má stáhnout. Tedy např.:
komponenta:
public function handlePdfExport()
{
$contents = $this->resultTemplate;
// vygenerovani pdf dle obsahu $contents
$filename = Model::generatePdf($contents);
$this->presenter->redirect(':Front:Download:', $filename); // mozna jde i $this->redirect
}
public function render()
{
echo $this->resultTemplate;
}
public function getResultTemplate()
{
.. ...
// nakonci nebude echo ... ale return ..., typicky tedy:
return $this->template->__toString(); // nebo return (string)$this->template;
}
DownloadPresenter:
public function renderDefault($filename)
{
$this->terminate(new DownloadResponse(Environment::getVariable('filesDir') . '/' . $filename, $filename, 'application/pdf'));
}
Snad to takhle půjde, nejsem si jistý.
Editoval Ola (23. 2. 2010 16:08)
- crempa
- Člen | 198
2Ola: diky to mozna bude ono, mel sem za to (a aspon dle schematu zivotniho cyklu to tak i vypada) ze handle je uz za vhodnym mistem pro redirect. Nevyhodu vidim v tom ze se musi neco ulozit na disk a teprve potom stahnout…
Idealni by byla moznost nejakeho interniho redirectu pouze v ramci zivotniho cyklu (tj. moznost interne se redirektnout na jiny presenter vcetne parametru ktery by treba nesl onu PDF binarku ktera by se pak uz jen poslala na vystup)
2honzakuchar: diky, ale to je asi pouze pripad kdy jde o cely presenter a ne jen o komponentu…
Editoval crempa (23. 2. 2010 17:09)
- Honza Kuchař
- Člen | 1662
Nene, je to na generování PDF ze ŠABLONY v šabloně může být klidně
jen jedna komponenta. Jak se tak dívám, tak v konstruktoru tomu můžeš
předat i string (html). Takže tam dej něco
jako $this->terminate(new PdfResponse($tvojeKomponenta->__toString()))
- Honza Kuchař
- Člen | 1662
Popřípadě můžeš generovat do souboru, ale na to tam není zkratka, takže si vytáhneě objekt mPDF a ten už to umí. ;)