9. ledna 2011

Generování PCL do souboru

Tento článek dnes píši z trochu jiných důvodů než jindy - rád bych si shrnul mé dosavadní znalosti v této oblasti a také bych vás rád požádal o radu, protože s touto problematikou nemám moc zkušeností.

PCL je formát používaný při tisku tiskárnami. Většinou se s tímto formátem člověk přímo nepotká, protože když někdo chce něco vytisknout, tak použije nějaký vhodný ovladač ke konkrétní tiskárně, ten PCL vygeneruje a pošle rovnou na tiskárnu k tisku.

Já mám k řešení trochu jiný problém. Moje aplikace tvoří část tiskového řešení, které je postavené na tom, že firma má po celém světě různé sklady a kanceláře, kde má síťové tiskárny. A podle určitých pravidel přijde nějaký dokument, ze kterého je potřeba vygenerovat PCL a poslat dle konfigurace na cílovou tiskárnu. Tiskárny jsou to většinou HP (řekl bych tak z 90%), sem tam se objeví i jiná značka, např. Xerox. Přenos souboru na tiskárnu je přes FTP.

Nemohu tedy využít konkrétní ovladače pro konkrétní tiskárny, musím vygenerovat nějaký obecný PCL soubor a ten tam poslat. Pokud se jedná čistě o textový soubor, tak ten se vytiskne bez potřeby generování PCL, ale ne všechny dokumenty jsou jen čistý text, někde jsou i obrázky.

PCL formát má řadu podformátů - 5e, 5c, 6. Ideální je (asi) verze PCL6, protože již dnes většina tiskáren podporuje tuto verzi a do budoucna bude rozšíření ještě větší. Navíc jednotlivé verze nejsou zpětně kompatibilní (někde se píše, že jsou zpětně kompatibilní a někde, že zase ne, ale spíše věřím tomu, že nejsou).

Další obecné požadavky na aplikaci - cílové OS je Linux (Redhat Enterprise) a velký důraz je kladen na rychlost, robustnost a škálovatelnost aplikace. Výsledný soubor k tisku musí být co nejmenší, řádově desítky kB.

Java Print Service

Java má celkem flexibilní API pro tisk - Java Print Service. Použití je přímočaré (ukázka generování z GIFu do PS) a v dokumentaci mezi podporovanými formáty PCL je, jenže při bližším zkoumání zjistíte, že PCL je podporováno jen na rozhraní a ne implementačně - "The StreamPrintService from JDK 6 does only support PS...".

Nenašel jsem žádnou knihovnu třetí strany, která by toto implementovala.

Apache FOP

Když se člověk poprvé při řešení tohoto problému porozhlédne po internetu, tak jako první většinou najde Apache FOP, který umí převádět data do PCL.

Bohužel podpora PCL v Apache FOP není dokonalá a má spoustu nevýhod:
  • celkem složité na implementaci, navíc těžko říci, zda to bude také rychlé. Je potřeba různě generovat XML, pak je transformovat atd. Určitě nic extra rychlého.
  • umí jen PCL5 a podpora PCL6 asi ani nebude.
  • neumí UTF-8 (Multibyte characters are not supported)
  • přehled dalších omezení

FO procesorů je více (zde je přehled), ale žádný jiný neumí PCL a nebo nejsou vhodné k použití s Javou.

Command-line a tiskové nástroje

Při hledání možného řešení jsem i prohledal všechny možné tiskové a konverzní nástroje, bohužel bez přímé podpory pro PCL.
I kdybych našel vhodný nástroj pro konverzi do PCL, tak zde vidím spoustu dalších nevýhod: nejsou to úplně levná řešení, pomalé a nevýkonné řešení, problém s integrací do naší aplikace, kód a další vývoj produktu nemám pod kontrolou.

Generování přes drivery

Při nějakém dalším zkoumání mě napadlo využít nějaký obecný driver pro tiskárnu, tj. poslat dokument k tisku na vhodný driver, ale místo na tiskárnu, tak výstup uložit do souboru.

Našel jsem "HP Universal Print Driver", ale ten je pouze pro Windows, já potřebuji Linux.

Pro Linux mě zaujal projekt Gutenprint a obecný driver Generic PCL 6/PCL XL Printer.

Podle mých slabých znalostí v této oblasti mám dvě možnosti - použiji program ghostscript a vygeneruji PCL z PS. Ghostscript by měl být součástí distribuce. Druhou variatnou je vyrobit virtuální tiskárnu, která se tváří jako PS tiskárna a interně použije ghostscript jako filtr na výrobu konkrétního tiskového formátu.

Chybí mi v této oblasti znalosti, jak by se to vůbec dalo na Linuxu zrealizovat, nicméně mám pocit, že tato cesta je celkem reálná, a že by mohla fungovat.

Něco jiného než PCL?

Když se podíváte na podporované formáty u lepších (=síťových) tiskáren, tak často jsou ještě vidět dva další formáty - PDF a Postscript.

PDF musím hned vynechat, protože podpora není nic moc - v mém vzorku cca 20 řad tiskáren (nemyslím konkrétní modely, ale celé řady tiskáren, např. HP LaserJet P4015 Printer series) je podpora u cca 50% a to je málo.

Pak se nabízí Postscript, podpora asi u 85% tiskáren. Generování do PS je přímočaré, protože to umí přímo Java Print Service ve standardní Javě. Jedinou nevýhodou, kromě slabší podpory u tiskáren než má PCL, je výsledná velikost souboru a nároky na systémové prostředky při generování. Z mých testů vyplynulo, že pro naše typové dokumenty je velikost PS 3x větší než PCL. Hned je ale potřeba dodat, že výsledné velikosti PS byly okolo 10kB, takže minimální.
"PS used to come at a price - it use to be the case that you had to pay extra money to get PS but now its fairly standard on many printers and indeed some HP printers will even print PDF directly. PS is generally considered more resource hungry - it requires more memory and is slower than PCL5/PCL6.
PS output files are usually larger than those generated for PCL5/PCL6 because it is plain ASCII, you can actually read it ; BUT communication times (between computer and printer) used to be slower."

Generování do PS již naše aplikace umí a zdá se, že vše běhá celkem rychle. Bohužel business požadavek je od začátku PCL.

Další informace:


Budu moc rád, pokud mi někdo poradíte a posunete mě dál. Já osobně nyní nejvíce věřím řešení přes drivery v OS.

1. ledna 2011

Knihovny pro testování: MockFtpServer a GreenMail

Minulý rok jsem toho napsal zatím nejméně a rád bych, aby to ten letošní rok bylo lepší. Proto píšu hned první den - jak se říká, jak na nový rok, tak po celý rok :).

Na posledním projektu jsem měl potřebu si ověřit správnou komunikaci s FTP serverem a posílání/přijímaní mailů, tedy komunikace se SMTP serverem a IMAP resp. POP3 serverem.

Pro komunikaci s FTP serverem jsem použil knihovnu Apache Commons Net. Nejdříve jsem chvíli přemýšlel, zda mi nebude stačit podpora ve standardní Javě (pro moje potřeby naprosto dostačující), ale nakonec jsem si vybral Commons Net. Rád a často používám knihovny s rodiny Commons a i zde jsem rád, že jsem tuto knihovnu vybral.
Pro testování komunikace s FTP serverem jsem našel výbornou knihovnu MockFtpServer. Dokáže opravdu věrohodně simulovat FTP server, zejména možnosti nastavení práv souborového systému jsou super.


Pro odesílání mailů používám podporu ve Springu - JavaMailSenderImpl. Kromě odesílání jsem potřeboval maily i přes IMAP stahovat, vytvářet složky na mail serveru a s maily různě manipulovat. Čekal jsem, že najdu nějakou vhodnou knihovnu, ale nakonec jsem skončil u standardní Javy, která nabízí JavaMail API. Některé věci jsou možná až moc nízkoúrovňové, ale nic lepšího jsem nenašel.

Pro testování mailů jsem využil knihovnu greenmail. Jako jedna z mála knihoven, které jsem našel pro testování, umí kromě ověřování SMTP i IMAP/POP3 protokol.

Pokud někdo potřebuje testovat jen SMTP, tak pro to by asi úplně stačila knihovna SubEtha SMTP.