[addon pdfresponse] PdfResponse
- jarks
- Člen | 94
Jak se dostat k datům?
Mám složitou stránku se zobrazenými daty. Potřebuji vygenerovat PDF soubor
s částí těchto dat. Následující ukázka kódu mi funguje, ale myslím,
že je zbytečné znovu se ptát databáze, když data už mám v
$this->template
. Ale nevím jak se k nim dostat, signál je
nevidí. Zkouším to všelijak, ale bez úspěchu.
V šabloně:
<a href="{link PDFProtokol! $produkt->id}">Protokol</a>
V prezenteru:
public function renderDetail($id) {// toto je hlavní stránka
$this->template->produkt = $this->getDetailModel()->findDetail($id)->fetch();
}
public function handlePDFProtokol($id) {// a toto vygeneruje PDF
$template = $this->createTemplate()->setFile(APP_DIR."/templates/Detail.PDFProtokol.phtml");
//Následující řádek vynechat a místo něj nějak do $template načíst data z hlavní šablony:
$template->produkt = $this->getDetailModel()->findDetail($id)->fetch();
$pdf = new PDFResponse($template);
// nějaké konfigurace PDF
$this->terminate($pdf);
}
Mohl bych prosím dostat radu jak v druhé metodě do $template dostat data už jednou načtená v první metodě do $this->template?
- Aurielle
- Člen | 1281
public function renderDetail($id) {// toto je hlavní stránka
$this->template->produkt = $this->produkt = $this->getDetailModel()->findDetail($id)->fetch();
}
public function handlePDFProtokol($id) {// a toto vygeneruje PDF
$template = $this->createTemplate()->setFile(APP_DIR."/templates/Detail.PDFProtokol.phtml");
//Následující řádek vynechat a místo něj nějak do $template načíst data z hlavní šablony:
$template->produkt = $this->produkt;
$pdf = new PDFResponse($template);
// nějaké konfigurace PDF
$this->terminate($pdf);
}
- Honza Kuchař
- Člen | 1662
To co píšeš, tak nebude fungovat… https://doc.nette.org/…n/presenters#…
Ale, čemu vadí, že ty data načítáš jakoby 2×. Ty je 2× nikdy nenačteš! V té metodě handle se volá terminate a to ukončí aplikaci!
Vždy, než použiješ nějakou metodu, o které nevíš co dělá, se podívej do API, kde je to všechno popsáno. https://api.nette.org/nette/0.9/
- Honza Kuchař
- Člen | 1662
gmvasek napsal(a):
Tak to se omlouvám za mystifikaci, příště si to radši vyzkouším než to sem pošlu…
Pokud si životní cyklus presenteru ještě nepamatuješ, doporučuji ti si
ho vylepit na monitor společně se zkaratkami k NetBeans tvému
IDE (a pinu ke kreditní kartě :-) ).
Editoval honzakuchar (22. 4. 2010 13:02)
- Oggy
- Člen | 306
Honza Kuchař napsal(a):
Chybu hledej na straně mPDF. Případně zkus soubor někam uložit a pak na něj vypusť FileDownloader. (doplňky)
Jakým způsobem provádí vygenerování pdfresponse v presenteru a jeho
uložení na disk?
pokud vytvoření pdfresponse je v action, tak je potřeba simulovat
httprequest?
nebo na ne?
:-)
díky
- Honza Kuchař
- Člen | 1662
Oggy napsal(a):
Honza Kuchař napsal(a):
Chybu hledej na straně mPDF. Případně zkus soubor někam uložit a pak na něj vypusť FileDownloader. (doplňky)
Jakým způsobem provádí vygenerování pdfresponse v presenteru a jeho uložení na disk?
pokud vytvoření pdfresponse je v action, tak je potřeba simulovat httprequest?nebo na ne?
:-)
díky
Moc ti nerozumím, ale hledej obsah metody send v IPresenterResponse. Tedy spíš její implementaci v PdfResponse.
- Oggy
- Člen | 306
Honza Kuchař napsal(a):
Moc ti nerozumím, ale hledej obsah metody send v IPresenterResponse. Tedy spíš její implementaci v PdfResponse.
ok..díky kouknu..
zjednoduším to na .. Jak vygenerovat pdf a uložit na disk v presenteru?
..
ukázku v dokumentaci je taková, že se pdf vygeneruje v action a uživateli
se pdf nabídne ke stažení..
ale dejme tomu, že při ukládání objednávky si ji chci vygenerovat v pdf a uložit na disk.. a pak stahovat již klasicky nebo filedownloaderem..
- Honza Kuchař
- Člen | 1662
Vytáhnu si objekt mPDF a uložím si ho kam potřebuji. Vůbec ho nepředám presenteru jako response (nezevolám $this->terminate()). Ale je to dobrý tip na přidání. Jednoduché a praktické a navíc to teď v jednom porojektu budu taky potřebovat. :)
($pdf je PdfResponse) ($pdf->mPDF je instance třídy mPDF)
$pdf->mPDF
- iguana007
- Člen | 970
Honza Kuchař napsal(a):
($pdf je PdfResponse) ($pdf->mPDF je instance třídy mPDF)$pdf->mPDF
Pokud to dobře chápu, tak by mi měl potom fungovat tento zápis:
$pdf->mPDF->Output($filePath, 'F');
což se mi v podstatě vykoná, pdf se mi v dané složce vytvoří, ale PDFko je prázdné, takže asi něco dělám špatně …
- zarubik
- Člen | 31
V podstatě ano, ale nefunguje :-D
Pokud chci uložit soubor na server s použitím:
$pdf->mPDF->Output($file, 'F');
V PDF se zobrazí pouze hlavička a patička souboru.
Abych zachoval chování PdfResponse upravil jsem funkci „send“:
public function send($name='', $dest='I') {
// stejné, pouze jsem upravil poslední řádek:
// $mpdf->Output(String::webalize($this->documentTitle),'I');
// na:
if($dest=='I'){
$name = String::webalize($this->documentTitle);
}
$mpdf->Output($name, $dest);
}
Víc jsem to neřešil.. potřeboval jsem to rychle rozchodit a funguje to :)
Možná by bylo lepší v PdfResponse přejmenovat funkci „send“ (tak jak ji mam upravenou) na Output. A send by pak vypadalo takto:
public function send() {
$this->Output(String::webalize($this->documentTitle), 'I');
}
Editoval zarubik (15. 10. 2010 9:51)
- Mikulas Dite
- Člen | 756
Pomocí hlaviček, ale funguje to jenom pokuď má uživatel nějaký software (příklad: Adobe Reader na Windows nebo Preview na Mac).
Content-Disposition: inline
- Scorpio
- Člen | 45
Supr dik jen kam ten radek mam umistit. takhle mi to stale nabizi ke stažení
$pdf = new PDFResponse($html);
$pdf->mPDF->OpenPrintDialog();
header("Content-Type: application/pdf");
header("Content-Disposition: inline");
$this->terminate($pdf);
Editoval Scorpio (1. 1. 2011 11:40)
- Mikulas Dite
- Člen | 756
Koukni se, jestli ti to ty hlavičky opravdu vrací. Jestli ne, je to moc
pozdě je upravovat. Ale nemělo by být, jestli tohle máš nejpozději v
render()
.
- Scorpio
- Člen | 45
Jinak ukladani mi to vyhazuje ve firefoxu v googlechrome to normalne ukaze rovnou. Tohle je vypis hlavicek
Date Sat, 01 Jan 2011 17:19:51 GMT
Server Apache/2.2.15 (EL)
X-Powered-By Nette Framework
Expires Sat, 26 Jul 1997 05:00:00 GMT
Cache-Control public, must-revalidate, max-age=0
Pragma public
Content-Disposition inline; filename="100691"
Content-Length 44562
Last-Modified Sat, 01 Jan 2011 17:20:14 GMT
Connection close
Content-Type application/pdf
http://zivogosce.tk/…/tisk/100691
chci to vypsat do tohoto iframu
tohle je presenter:
function renderFaktura($id) {
header("Content-Type: application/pdf");
header("Content-Disposition: inline");
$html = file_get_contents("http://".$_SERVER['HTTP_HOST']."/html/faktura/".$id);
$pdf = new PDFResponse($html);
$pdf->documentTitle = $id;
$pdf->mPDF->OpenPrintDialog();
$this->terminate($pdf);
}
Editoval Scorpio (1. 1. 2011 18:35)
- Filip Procházka
- Moderator | 4668
// tip na vylepšení
$faktury = Nette\Environment::getCache('Faktury');
$html = $faktury->call('file_get_contents', "http://".$_SERVER['HTTP_HOST']."/html/faktura/".$id);
$pdf = new PDFResponse($html);
$pdf->documentTitle = $id;
$pdf->mPDF->OpenPrintDialog();
// takhle se to dělá nette-way
Nette\Environment::getHttpResponse()->setHeader('Content-Disposition', 'inline');
$this->sendResponse($pdf);
s tím iframem možná bude problém, afaik si nejsem jistý jestli je to vůbec možné
- Mikulas Dite
- Člen | 756
Otázka je, proč zobrazovat pdf? To si vygeneroval z nějakého html, tak zobraz to. Proč to by to nešlo?
- Honza Kuchař
- Člen | 1662
Kryšpin napsal(a):
Jen přípomínka, že odkaz na diskuzi o tomto skvělém doplňku na jeho stránce vede na neexistující vlákno.
Díky moc, opraveno.
- Chbox
- Člen | 125
nějak se mi nedáří rozchodit ukládání do souboru :-(
public function actionPdf() {
$template = $this->createTemplate()->setFile(APP_DIR."/FrontModule/templates/Pdf/pdf.latte");
$pdf = new PDFResponse($template);
$pdf->mPDF->Output(CV_DIR . '/' . $this->user->id . '.pdf', 'F');
//Ukončíme presenter -> předáme řízení PDFresponse
$this->sendResponse($pdf);
}
pokud zakomentuju $pdf->mPDF->Output, výstup na obrazovku je
v pořádku,
jinak to generuje prázdnou stránku jak do souboru, tak ..
..co s tím, pomóc? :-)
- basovnik
- Člen | 23
Ahoj, nejde mi rozchodit PDFResponse. Neporadili byste mi?
Tohle funguje v pohode:
<?php
function handlePdf($id)
{
$html = "<b>ahoj světe!</b>";
$this->terminate(new PDFResponse($html));
}
?>
Tohle uz ne:
<?php
function handlePdf($id)
{
$template = $this->createTemplate()->setFile(APP_DIR."/AdminModule/templates/Offers/pdf.latte");
$this->terminate(new PDFResponse($template));
}
?>
Vypíše mi to chybu Chyba 101(net::ERR_CONNECTION_RESET): Neznámá
chyba.
Používám Nette 2, PHP 5.3
Snad mi někdo poradí, už jsem bezradný :-(
Editoval basovnik (2. 3. 2011 20:40)
- maChy
- Člen | 9
Chbox napsal(a):
nějak se mi nedáří rozchodit ukládání do souboru :-(
public function actionPdf() { $template = $this->createTemplate()->setFile(APP_DIR."/FrontModule/templates/Pdf/pdf.latte"); $pdf = new PDFResponse($template); $pdf->mPDF->Output(CV_DIR . '/' . $this->user->id . '.pdf', 'F'); //Ukončíme presenter -> předáme řízení PDFresponse $this->sendResponse($pdf); }
pokud zakomentuju $pdf->mPDF->Output, výstup na obrazovku je v pořádku,
jinak to generuje prázdnou stránku jak do souboru, tak ..
..co s tím, pomóc? :-)
Docela mě to vrtalo v hlavě proč mi to taky vyhazuje prázdný dokument, chvíli mi trvalo než jsem přišel jak to vyřešit.
přez $df->mPDF->Output voláš výstup ještě ve chvíli, kdy nemá žádné data. Proto se zobrazí prázdný. Dá se to obejít velmi elegantně, využitím proměných…
<?php
$html = "<b>ahoj světe!</b>"; // HTML v UTF-8
// Jako 1. parament PDFResponse můžeme předat html v UTF8 nebo objekt implementující rozhraní ITemplate
$pdf = new PDFResponse($html);
$pdf->documentTitle = 'Testovací dokument číslo 1';
$pdf->outputName = './download/soubor.pdf';
$pdf->outputDestination = 'F';
$this->sendResponse($pdf);
?>
v tomto případě se soubor uloží do www/download/ a ještě bude k dispozici na stažení!
Editoval maChy (5. 3. 2011 21:12)
- Scorpio
- Člen | 45
Ahoj mohl by mi nekdo poradit snazim se vygenerovat stranku v LANDSCAPE modu ale vraci se mi stale PORTRAIT. Jel sem presne podle navodu na strance modulu ale i to mi vraci PORTRAIT. Nemáte s tímhle někdo zkušenosti?
$pdf = new PdfResponse($html);
$pdf->pageFormat = "A4";
$pdf->pageOrientaion = PdfResponse::ORIENTATION_LANDSCAPE;
$pdf->pageMargins = "0,0,0,0,0,0";
$pdf->mPDF->OpenPrintDialog();
$this->terminate($pdf);
Editoval Scorpio (9. 3. 2011 12:00)
- maChy
- Člen | 9
Scorpio napsal(a):
Ahoj mohl by mi nekdo poradit snazim se vygenerovat stranku v LANDSCAPE modu ale vraci se mi stale PORTRAIT. Jel sem presne podle navodu na strance modulu ale i to mi vraci PORTRAIT. Nemáte s tímhle někdo zkušenosti?
$pdf = new PdfResponse($html); $pdf->pageFormat = "A4"; $pdf->pageOrientaion = PdfResponse::ORIENTATION_LANDSCAPE; $pdf->pageMargins = "0,0,0,0,0,0"; $pdf->mPDF->OpenPrintDialog(); $this->terminate($pdf);
S tím jsem taky zápsali, vyzkoušel jsem nahrát i novou verzi mPDF 5.1 nepomohlo. Zkoušel jsem upravit i kód PDFResponse, taky nepomohlo. Nakonec jsem koukl do dokumentace u mPDF a zjistil jsem, že to jde nastavit i v css šablony stačí přidat:
<style>
@page { sheet-size: A4-L; }
</style>
Editoval maChy (10. 3. 2011 22:58)
- Honza Kuchař
- Člen | 1662
A také přidána podpora pro obrázky v těle dokumentu zakódované klasicky pomocí base64. mPDF to umělo jen s velmi malými soubory. PdfResponse opravuje tuto chybu a nyní jde vkládat jakkoli veliký obrázek pomocí base64. (od 2.3.) A nyní 1.9.2011 opravena chyba s opravdu velikými obrázky vloženými pomocí base64.
Editoval Honza Kuchař (1. 9. 2011 17:42)
- Inferi
- Člen | 18
Ahoj,
řeším zde podobný problém ohledně zobrazení pdf. Problém je, že pokud do konstruktoru předám $template, tak mi najede bílá stránka. Když si výstup uložím do proměnné napřímo, př. <a>…</a>, tak to se vytiskne v pořádku. Nicméně potřebuji tisknout naplněnou šablonu a ne skládat vzled řetězením částí databáze do stringu.
try{
$articles = new \AdminModule\ArticlesModel();
$this->article = $articles->getArticle($this->lang, $this->previous, ($this->id == "")?$mainArticles[0]->alias:$this->id);
}
catch(DibiException $e){
$this->flashMessage($e->getMessage(), 'error');
$this->redirect('dafault', $this->lang, $this->id);
}
$template = $this->createTemplate()->setFile(APP_DIR."/FrontModule/templates/Homepage/print.latte");
$template->article = $this->article;
$pdf = new \Pdf\PdfResponse($template);
$pdf->documentTitle = 'Testovací dokument číslo 1';
$this->sendResponse($pdf);
Nějaké zkušenosti, řešení? (Php 5.3, Nette 2.0)
- Honza Kuchař
- Člen | 1662
Ahoj,
nejspíš jsi špatně přepsal PdfResponse do namespacované verze. Podíval
jsem se do zdrojového kódu a opravil jsem né příliš dobře povedené
získávání zdrojového dokumentu. (když si uděláš diff, přeneseš si
změny během pár sekund do té tvé namespacované verze)
Sice to asi nebude řešit přímo tvůj problém, ale pokud ti to skončí
na posledním řádku metody getSource()
chybu jsi udělal na
9. řádku funkce getSource()
, kde se zjišťuje, jestli je to
šablona či ne.
Pokud ani to nepomůže dá se nad třídnou Template použít volání
magické metody __toString()
. Resp. __toString(true)
,
která bude v případě chyby vyhazovat výjimku (doporučeno).
- Honza Kuchař
- Člen | 1662
@Scorpio a @MaChy: Navrhujete tedy odstranit přepínač ladscape a portrait režimu?
Prozatím tam přidávám komentář k $pageOrientaion.
- trubi
- Člen | 25
Zdravicko, snazim se udelat, aby se po zobrazeni pdf v prohlizeci ihned zobrazit print dialog. PDF se mi v prohlizeci zobrazi, ale to je vse.
<?php
public function actionPrint() {
// .....generovani template
$pdf = new PDFResponse($template);
header("Content-Type: application/pdf");
header("Content-Disposition: inline");
$pdf->mPDF->OpenPrintDialog();
$this->sendResponse($pdf);
}
?>
$pdf->mPDF->OpenPrintDialog(); je napsane v addons, ale nepodarilo se mi tuto funkci najit nikde v dokumentaci mPDF. Muzete mi poradit co delam spatne, prip. jak tuto funkcionalitu zprovoznit? Diky
- Honza Kuchař
- Člen | 1662
Metoda je definovaná zde:
https://svn.mujserver.net:8443/…Extended.php
Víc ti asi neporadím, protože mně to funguje.
- tatyalien
- Člen | 239
Kryšpin napsal(a):
Kdo bude zprovozňovat tento doplněk pod PHP 5.3 a Nette 2.0 dev, tak jen přidat do
PDFResponse.php
<?php use Nette\Object, Nette\Callback, Nette\Environment, Nette\String; class PdfResponse extends Object implements Nette\Application\IPresenterResponse { .... } ?>
No zkoušel jsem to jak píšeš, ale hodí mě to pak:
Declaration of PDFResponse::send() must be compatible with that of
Nette\Application\IPresenterResponse::send()
Když si najedu na na send, je tam:
if ($this->source instanceof ITemplate) {
a i když to opravím na Nette\Templates\ITemplate tak stejný problém.
- bojovyletoun
- Člen | 667
to, co opravuješ není chyba. Chyba se opraví tak, aby hlavička funkce
send (toto: function send(**TytoParametry**)
) v PDFResponse a b
IPresenterResponse byla stejná.
- tatyalien
- Člen | 239
zajímavé, a to jsem ale stejně jen překopíroval ze zdroje šablony, PdfResponse, presenter a hází to toto ;)
No nic, tak odsouvám generování až za delší dobu… Bez nette jsem si mohl generovat pdfka jen pomocí fpdf a fontu, na serveru (fpdf.php cca 44kb, arial 33kb) tohle má 16mega a stejně mě to nefrčí :-D)
- net-vor
- Člen | 35
Drobná poznámka pro ty, kdo chtějí rozchodit PdfResponse pro PHP 5.3: aby to fungovalo, je třeba nejdřív natáhnout tyto prostory:
use Nette\Object, Nette\Application\IPresenterResponse, Nette\Callback, Nette\Environment, Nette\String;
a to přímo v Honzově souboru
libs/PdfResponse/PDFResponse.php
. Pak to šlape jak hodinky.
Editoval net-vor (25. 5. 2011 14:00)
- Tracy
- Člen | 8
Hola :)
Je to trosku trapny, ale nedari se mi to rozchodit ani naznakem :(
Nette Framework 2.0-beta pro PHP 5.3 se jmennými prostory
Kdyz necham vsecko tak jak je, pridam to co je o post nademnou, tak mi krasna ladenka vynada
Interface ‚Nette\Application\IPresenterResponse‘ not
found
No a ma pravdu, IPresenterResponse.php neexistuje.
kdyz nahradim IPresenterResponse ⇒ IResponse, tak mi serve
Declaration of PdfResponse::send() must be compatible with that of
Nette\Application\IResponse::send()
Coz resil uz kolega…
Chyba se opraví tak, aby hlavička funkce send (toto: function send(TytoParametry)) v PDFResponse a b IPresenterResponse byla stejná.
Nicmene at do toho vrtam jak do toho vrtam, ucinek nulovej.
Muze mi nekdo, prosim, rict jak z toho ven?
Editoval Tracy (11. 7. 2011 17:34)
- boky
- Člen | 18
Tracy napsal(a):
Hola :)
Je to trosku trapny, ale nedari se mi to rozchodit ani naznakem :(
Nette Framework 2.0-beta pro PHP 5.3 se jmennými prostory
Kdyz necham vsecko tak jak je, pridam to co je o post nademnou, tak mi krasna ladenka vynada
Interface ‚Nette\Application\IPresenterResponse‘ not found
No a ma pravdu, IPresenterResponse.php neexistuje.kdyz nahradim IPresenterResponse ⇒ IResponse, tak mi serve
Declaration of PdfResponse::send() must be compatible with that of Nette\Application\IResponse::send()Coz resil uz kolega…
Chyba se opraví tak, aby hlavička funkce send (toto: function send(TytoParametry)) v PDFResponse a b IPresenterResponse byla stejná.
Nicmene at do toho vrtam jak do toho vrtam, ucinek nulovej.
Muze mi nekdo, prosim, rict jak z toho ven?
Cau,
nejak sem se stim popral… snad ti to pomuze
use Nette\Object, Nette\Application\IResponse, Nette\Callback, Nette\Environment, Nette\Utils\Strings, Nette\Templating\Itemplate;
class PdfResponse extends Object implements IResponse {
public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {