Zajímavou a vyše nezmíněnou možností je také knihovna IText. http://www.lowagie.com/iText/download.html
Pomocí ní je možné generovat PDF přímo v kódu JAVY. Je pod licencí MPL a LGPL (předpokládám, že volně použitelná). Na domovské stránce je podrobně popsáno použití a mnoho příkladů.
Pro komplexnější řešení to asi není. To by se člověk upsal. Ale pro nějaké rychlé nebo speciální řešení je to zajímavá alternativa.
jakub: "...Pro komplexnější řešení to asi není..."
Ano, pre komplexnejsie zostavy odporucam JasperReports http://jasperreports.sourceforge.net/ , ktory vyuziva iText ako engine. Zostavy su definovane v XML, ale mozete pouzit aj WYSIWYG editor iReport http://ireport.sourceforge.net/
Samozrejme vsetko je to open-source :-)
No my jsme zkoušeli různé reportovací nástroje a narazili jsme na problémy.
Oni sice existují WYSIWYG návrháře, ale mají velká omezení - např. špatně se dělají subreporty, ....
Pokud je přímo napojujete na databázi musíte všechna omezení přetrpět.
Nakonec jsme začali používat UJAC. Je to podobné HTML. Prostě vygenerujeme XML tagy pomocí šablonovacího jazyka (freemarker) a pak to celé necháme naformátovat pomocí UJAC.
My sme spokojni s kombinaciou JasperReports+iReport, hlavne preto ze zdroj dat nemusi byt priamo JDBC, ale kolekcia objektov. Ja osobne som pred 5-6 rokmi robil vela zostav vo VB5 a CrystalReports, a vtedy som strasne nadaval, lebo zdrojaky Crystalu boli binarne. Prave zdrojaky v XML u Jasperu povazujem za velku vyhodu.
ta metoda, ze nejaka aplikace vytvori "stream" dat, ktery nejaky filtr zachyti a zpracuje do vystupniho formatu ANIZ by tento filtr nejakym zpusobem mohl zpetne komunikovat s aplikaci, ktera ten "stream" vyrabi funguje jen do "stredne" problematickych reportu. Pri vetsi komplexite se nelze vyhnout primemu vytvareni dokumentu z nejake aplikace za pomoci nejakeho jazyka - nejlepe interpretacniho...
Vyhnout se tomu jde, akorát se to formátování musí provést v několika průchodech, kdy se výsledek předchozího kola formátování může použít jako jeden ze vstupů do kola dalšího.
Nevím jestli tohle zvládá FOP, ale komerční implementace XSL-FO (třeba XEP) to umí, a jde s tím udělat už opravdu vše (s čím jsem se zatím setkal:-).
ne, nejde to z principielnich duvodu, neni to tedy otazka jestli je nejaky produkt (filtr) lepsi nebo horsi a nebo jestli jiz ma neco implementovano, co konkurence jeste neovlada.
Beznym prikladem je faktura, kde se podle velikosti doprovodneho textu podari vytisknout jednou 5 a jindy treba 15 pozic. Na konci stranky je zapotrebi vydat sumy platne pro tuto stranku pricemz sumy se deli na zakladni castku a castku za doplnky - pricemz JEN aplikace je v danem okamziku sto rozhodnout, ktere z vytistenych pozic jsou obsahem zakladni dodavky a co jsou doplnky. Filtr by to mohl zjistit jen tak, ze by se v okamziku formatovani zeptal aplikace, co je treba nyni vytisknout, ale aplikace treba jiz nezije, nebot vyrobila stream pred dvema dny.
Samozrejme ze existuji pokusy zabudovat do formateru (filtru) callback funkce, ktere by komunikovaly s nejakou aplikaci, databazi, coz samozrejme take nevede k cili, nebot udaje v databazi mohou byt jina, nez v okamziku produkce onoho streamu dat.
Samozrejme, ze se jedna o komplikovane pripady ale i ty je treba resit a protoze z duvodu vyskytu takoych pripadu je interpreter zapotrebi, je nasnade ze se nasadi i na ty pripady jednodussi...
Jestli to je informace, ktera je nutna pri tisku a zaroven to vi jen aplikace, pak udelal autor streamu chybu. Zakladnim predpokladem spravnosti reseni je to, ze aplikace poskytuje vsechny dulezite informace. Co je dulezite specifikuji vsechny prvky retezu (aplikace, filtry, vizualizace).
asi jste presne nepochopil o co jde. My nehledame, jestli je nekdo vinen, jde o to, ze "prakticky" NENI mozne u komplikovanych reportu zaslat vsechny "dulezite" informace.
Tedy jeste jednou, ja odpovidal panu Koskovi na jeho mineni, ze pomoci mechanizmu roury (nebo retezu, jak pisety vy) lze realizovat i komplikovane reporty. (komplikovane jsou vesmes takove, ktere maji vice stranek a vyzaduji nejake mezisoucty apod). Toto neni definitivne mozne, protoze aplikace nemuze tusit jak bude probuhat proces formatovani a filtr/tisk zase netusi, jaka data bude zpracovavat. Jedine reseni teto situace je to (jak jsem psal), ze vse bude realizovane v jednom programu...
Přiznám se, že této argumentaci nerozumím. Pokud mám informaci a umím ji použít, pak jsem schopen ji zapsat do XML, třeba označit pomocí nějakého atributu. Pokud jsem s takovým atributem nepočítal, pak mám chybu v návrhu. Pokud uživatel ten atribut nepoužil, má chybně zadaná data. Pokud neexistuje možnost, jak informaci uložit v XML, pak pochybuji, že se dá vůbec nějak využít a je diskutabilní, jestli nějakou informaci mám.
U nás ve fy děláme něco jako ReportBuilder. Právě tyto věci jsou řešeny scriptováním na straně report builderu.
Pokud jsou řádky ve faktuře různě vysoké, přičemž velikost se řídí obsaženým textem, opravdu nikdo neví, kolik řádků na stránku se vejde na stránky než to je vyrenderováno.
No průběžné mezisoučty jde v XSL-FO udělat jedním průchodem (přes fo:marker). Pokud se jedná o součty pouze za jednu stránku, jde to bez problémů vyřešit dvěma průchody. Není potřeba přitom nějak zpětně komunikovat s aplikací, která daa generoval. Proces vypadá tak, že se v první fázi na XML aplikuje XSLT, které generuje FO. To se však neppřevede do PDF, ale do XML dokumentu, který u jednotlivých textů definuje, kde se na stránce vyskytují, jakým jsou fontem apod. Kromě toho se do tohoto dokumentu vloží (pomocí extenze XSL-FO značky, indentifikující jednotlivé položky reportu).
V druhém kole XSLT transformace na vstupu bere originální XML plus výsledek formátování z prvního kola. Díky informacím o layoutu a neviditelným identifikátorům položek ví, které položky jsou spolu na stránce a může je sečíst a součet vložit na konec stránky.
S tímto přístupem jde řešit opravdu složité situace, a zatím jsem v praxi nenarazil na situaci, která by tímto postupem nešla řešit (pravda někdy jen dva průchody nestačily).
Ano, máte pravdu v tom, že velmi složité reporty se nedají pomocí "jednocestného" filtru většinou vytvářet. V reálných informačních systémech to také může vypadat tak, že se export provede do Excelu a všechny další zpracování se udělají buď ručně nebo pomocí maker (cesta je to sice trnitá, ale pro mnoho firem i úřadů je to kupodivu zdaleka nejlevnější řešení).
Ze by byl problem v hrubem nepochopeni vyrazu "Jednocestny filtr"? Jednocestny znamena, ze jednorazove nacte data, zpracuje je (napriklad makra v excelu, uzivatel u klavesnice) a pak jednorazove poskytne vysledek.
Vami popsane reseni s excelem je jednocestne. Tedy pokud jeho soucasti neni zvednuti telefonu a domahani se doplnujicich informaci u 'dodavatele' vyexportovaneho souboru.
No, myslel jsem to tak, ze exporty z IS jsou vetsinou nedodelky. To neni ani tak problem programatoru (spis nedostatecne analyzy problemu), jako koncepce vyvoje techto IS, ktere jsou vlastne porad o krok pozadu za pozadavky uzivatelu - ti totiz dopredu nevedi, co chteji :-).
Potom to vypada napriklad tak, ze se nejprve na Excelovskem "reseni" zjisti, co vlastne uzivatele pozaduji a potom se to teprve (kdyz jsou penize) zavede jako bezna operace do IS.
Vystup do Excelu je samozrejme temer vzdy jednocestny, zpetna vazba je sice mozna (makra s OLE nebo HTTP/SMTP), ale v realnem provozu to spis nefunguje, nez funguje.
My zase pro zmenu generujeme doc, xls, pdf pomoci z javy pomoci OpenOffice SDK. Staci spustit openoffice v rezimu server, pres UNO Runtime API se pripojite a vzdalene volate metody openoffice API. Jednoduse se timto zpusobem da naimplementovat konverze dokumentu nebo vyplnovani sablon. Umi samozrejme i vkladat obrazky, grafy, tabulky. Vyhodou je ze takovy dokument mate moznost ulozit/nacist z libovolneho formatu podporovaneho OpenOfficem vcetne PDF, RTF, XML atd. Podpora MS formatu je v OO bezkonkurencni. Nevyhodou jsou pomerne velke naroky na CPU/pamet. Openoffice navic neni schopen v rezimu server zpracovat vice dokumentu paralelne. Takze je nutne to cele zasynchronizovat. Dokonce existuje openoffice daemon napsany v pythonu, ktery ridi rozdelovani pozadavku na vice instanci openoffice serveru a automaticky restartuje OO server pokud z nejakeho duvodu spadne nebo nereaguje. Jooo, kez by se pri vyvoji OpenOffice 2.0 zamerili na vylepseni server modu a umoznili pralelni zpracovani, zlepsili performance, odstranili zbytecnou zavislost na X Window systemu...
Můžu se zeptat, jak to při praktickém nasazení vypadá s alokovanou pamětí? Nevím, jestli jsou v OO.org nějaké skryté memory leaky, ale při klasické "klientské" práci se alokovaná paměť pořád trošku zvyšuje :-(, což samozřejmě v běžném provozu příliš nevadí. Ale na serveru v režimu 24/7 to může způsobovat značné problémy ne? Nebo tam máte nastavený nějaký automatický či vynucený restart po x hodinách provozu?
Musi se korektne zavirat otevrene dokumenty, pri testovacim provozu jsme zatim s leakovanim problem nemeli. O dostupnost OO.org se stara daemon, ktery ho v pripade potreby restaruje. Pro aplikaci je to transparentni, nic nepozna, pouze vytvareni dokumentu trva o neco dele. Stav to neni idealni, ale doufam, ze casem na OO.org v teto oblasti trochu zapracuji.
Taky doufam, ze v dalsich verzich vylepsi funkcionalitu OLE apod. Zatim jsem testoval OO.org 2 (betaverze) a oprav ci novych veci tam moc neni, spis je videt, ze se vyvojari soustredili na uzivatelske rozhrani - osobne by se mi treba libily Reveals Codes z WordPerfectu, kdyz uz je jasne, ze v MS Office nikdy nebudou :-)