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.

2 komentáře:

Petr Jůza řekl(a)...

Příspěvek od Martina Bednáře:

MHO by nemel byt problem v CUPSu definovat fronty ktere to ukladaji do PCL fajlu dle typu tiskarny, pripadne do PS a to zkonvertovat Ghostscriptem a z Javy pouzit standardni tisk.
Vzhledem k tomu jakym zpusobem pouziva CUPS backendy, tak by mel jit napsat skript ktery ti to posle pres FTP na cilovou tiskarnu, nebo by to poslal zpet do Java aplikace a ta by se postarala o dalsi zpracovani toho PCL fajlu.

Na Macu je /usr/libexec/cups/backend kdyz si tady vyrobis skript ftp, tak pak muzes jako url te tiskarny uvest ftp://asdf/asdf a on ten tisk provede pres tvuj ftp skript.
V pripade linuxu je to nemlich stejne jen ty backendy jsou v /var/cups/backend tusim.

Anonymní řekl(a)...

Zdravím,

asi píši pozdě, ale máme velice dobré zkušenosti s programem JetPCL od americké společnosti Tech Know Systems. Převádíme pomocí tohoto programu PCL soubory do grafického PDF formátu (podporovány jsou různé OS). Možná tato informace pomůže.

Tomáš