Jak renderovat komponentu do PDF?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
crempa
Člen | 198
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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)

Honza Kuchař
Člen | 1662
+
0
-

https://componette.org/search/?…

Editoval honzakuchar (23. 2. 2010 16:51)

crempa
Člen | 198
+
0
-

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
+
0
-

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
+
0
-

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í. ;)

Ola
Člen | 385
+
0
-

crepma: není forward metoda presenteru to, co hledáš?