Jak na download PDF souboru v PHP?
Když jsem včera řešil generování PDF z HTML a následný download tohoto souboru, setkal jsem se s řadou problémů. Není to v praxi až tak triviální věc, jak to vypadá. Některé zasílané header()
hlavičky nefungují v MSIE, některé v Opeře, a jiné zase ve Firefoxu. Dospěl jsem nakonec k řešení, které funguje, dle testů, pod MSIE 6.0, Firefoxem 1.5 i Operou 9, a nabídne uživateli stažení vytvořeného PDF souboru.
Takto vypadá skutečně funkční download vyvořeného PDF v PHP:
function download_file($pdfdata, filename){ if (ereg('Opera(/| )([0-9].[0-9]{1,2})', $_SERVER['HTTP_USER_AGENT'])) $UserBrowser = "Opera"; elseif (ereg('MSIE ([0-9].[0-9]{1,2})', $_SERVER['HTTP_USER_AGENT'])) $UserBrowser = "IE"; else $UserBrowser = ''; $mime_type = ($UserBrowser == 'IE' || $UserBrowser == 'Opera') ? 'application/octetstream' : 'application/octet-stream'; header('Content-Type: ' . $mime_type); header('Content-Disposition: attachment; filename="'.$filename.'"'); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header('Accept-Ranges: bytes'); header("Cache-control: private"); header('Pragma: private'); header("Content-Length: ".strlen($pdfdata)); echo $pdfdata; }
Otestovat si jej můžete přímo pod tímto článkem kliknutím na [export do PDF].
Pěkná přístupná i použitelná věcička. Jen tak přemýšlím, kolik lidí tento export využije… prakticky mě ani nenapadá moc důvodů, proč exportovat do pdf.
Snad jen když si chci článek off-line archivovat.
Ten test browserů bych udělal benevolentnější - takto nebude fungovat v další Opeře (v10). Respektive možná ano, díky chybějícímu escapování tečky.
moc moc diky!
Podobný problém jsem nedávno řešil a vyřešil jsem ho stejně (tedy posíláním application/octetstream nebo application/octet-stream podle prohlížeče).
Co se mi ale nepodařilo vyřešit bylo, jak přimět IE, aby PDF přímo otevřel (tedy nenabízel ho ke stažení). V Firefoxu a Opeře to je bez problému, stačí poslat application/pdf a vyplivnout obsah, ale v IE to z neznámého důvodu nefunguje. Ví někdo jak na to?
[1] archivace článku, jeho offline čtení (divil by ses, kolik lidí to potřebuje), přenos článku do PDA pro jeho pozdější čtení, atd.
Vygenerované PDF má v sobě nějak podivně embeddované fonty, pokud vůbec nějak - při vypnutí volby "Používat lokální písma" se fonty v dokumentu celkem zprasí...
Možná jsem správně nepochopil význam tohoto článku, ale správně je jen application/octec-stream a nic jinýho. Pokud aplikace ignoruje tenhle MIME type, tak je to její chyba. Přiřazení MIME je snad jednou jasně definovaný v RFC a hotovo, nebo ne? Každopádně pdf by se měl posílat jen jako application/pdf a je jen na aplikaci (a hlavně na jejím nastavení, který múže mít každý uživatel jak sám chce), jak s tímhle typem dat naloží.
Jen pro zajímavost ... teď jsem si tohleto zkusil v IE 7 RC1, FF 1.5 i 2.0 a Opeře 9, vše v posledních updatech. Výsledek se dal očekávat, všechny to zkousnou ať už je tam cokoliv a vysvětlení je jednoduchý - všechny prohlížeče nekoukají na typ souboru, pokud mají v hlavičce uvedený, že ho mají nabídnout k uložení. Maximálně na ten typ mrknou, že by uživateli po stažení mohli nabídnout jeho otevření, ale to už spíš řeší podle koncovky souboru.
Něco jinýho by to bylo, pokud by místo Content-Disposition: attachment bylo inline ... pak by musel prohlížeč koukat po způsobu, jak ty data zobrazit. Ale v tomhle případě by se stejně měl jako MIME použít application/pdf.
Dík , výborný počin, teď mohu všechny vaše pro mně důležité články bez problemu ukládat.
Zrovna tenhle článek se hodí vyexportovat do PDF. :-)
Njn, osobně by mě fakt zajímalo, kde MIME nadělá víc užitku než škody, protože teď mě nic nenapadá. Vůbec celý koncept posílat metadata souboru mimo samotný soubor je imho zcestný, MS systémům odjakživa stačila jenom přípona jména souboru.
application/pdf by mělo fungovat ve všech browserech ne?
[1] Já jej někdy (pokud jej dotyčný blog/web podporuje) používám pro tisk, protože všechny weby nemají vytvořený tiskový styl, nebo mi daný tisk. styl nevyhovuje, PDF většinou obsahuje důležité infomace v rozumné formě...
Ahoj, neřešil jste někdo generování pdf přes třídu fpdf na webu který běží na SSL? Podle fpdf.org by to měla řešit úprava headers, ale nějak mi to nešlape a nebo jsem ještě nepřišel na správnou kombinaci úprav :)) Díky