A minap egy érdekes problémába ütköztem. Fejlesztek egy Mono-s alkalmazást, melynek mind Linux-on mind Windows-on futnia kell és ami a lényeg, nyomtatni is kell a programból. A program felületét Gtk#-al oldottam meg a platformfüggetlenség miatt, így a natív kinézet mindkét platformon megoldott és problémamentes. Voltak kísérleteim a Windows.Forms-al is, ez azonban a Mono-ban még nagyon hiányos. A Gtk pedig egyébként is közelebb áll a szívemhez. A fejlesztés egyik kritikus pontja volt a megfelelő felület kiválasztása, amely a Gtk#-al meg is oldódott. Nem is gondoltam, hogy a nyomtatás lesz az a terület, amely a legkomolyabb hiányosságokat fogja mutatni.
Egy szó mint száz a fejlesztés azon szakaszához értem, ahol a nyomtatás került volna megvalósításra, azonban azt kellett, hogy tapasztaljam ez nem fog olyan könnyen menni mint ahogyan azt előzőleg gondoltam. A .NET keretrendszerben a System.Drawing.Printing névtér felelős a nyomtatások megvalósításáért. Íme egy egyszerű példa:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
Az első probléma a PrinterSettings.InstalledPrinters property használatával jön elő. Ez a property volna felelős a renszerben telepített nyomtatók lekérdezéséért, melyeket egy StringCollection-ön keresztül ad vissza. Mono-val futtatva a kódot azonban NotImplementedException-el áll le futás a fenti nyomató lekérdezéshez érve. Ez összességében véve még nem jelentett volna számomra túl nagy problémát, hiszen a probléma áthidalható lenne. A beállításokat tartalmazó XML file-ba fel lehetne venni egy olyan értéket amely a program számára alapértelmezett - és természetesen a rendszerben telepített - nyomtató nevét tartalmazza és a programból csak azt kérdezném le. De mint kiderült ez csak a kisebbik probléma. Tulajdonképp a nyomtatás a Mono-ban - úgy ahogy van - még erős fejlesztés alatt áll. A PrintDocument.Print() metódus egy - ha több oldalas a dokumentum akkor több - Jpeg képet generál az aktuális könyvtárba ‘documentname xxxx.jpg’ néven, ahol az xxxx az oldal számát reprezentálja. A jelnség okát a forráskód OnEndPage() metódusában meg is találhatjuk:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Gondoltam arra, hogy számomra a generált Jpeg file-ok is megfelelőek lesznek a nyomtatási produktum előállításához, hiszen az lpr parancsot megfelelően felparaméterezve “bemásolhatom” a képet a nyomtatási sorba - amennyiben Linuxon fut a kód - és azzal le is tudtam a nyomtatást. Az elkészült kép minősége Linuxon azonban hagy némi kivetni valót maga után. Igényes minődégű dokumentumok sajnos így nem nyomtathatóak. Ott volna még az a lehetőség, hogy az OnEndPage() metódusban a System.Drawing.Imaging.ImageFormat osztály kimenetét TIFF-re, PNG-re vagy esetleg BMP-re módosítva javítani lehet a minőségen. Be kell azonban látni, hogy a Mono mainstream kódját módosítani önös célok érdekében nem érdemes, sőtt tűzzel, vassal megelőzendő.
Alternatív megoldást kellet, hogy találjak. Na igen, ott volt még a libgnomeprint, de irtóztam attól, hogy két eltérő megoldással működjön a nyomtatás - vagy bármely más funkciója a programnak - attól függően, hogy milyen platformon fut. Ez elsősorban a programozói lustaságomnak köszönhető, de egyébként sem tartom szerencsésnek, hogy a kód ennyire szerteágazzon.
Szerencsére találtam egy módszert, amely kiválóan megfelel az igényeimnek. Lehet, hogy nevetséges, de működik. Találtam a SourceForge-on egy library-t amely PDF file-ok készítésére alkalmas. A library neve sharpPDF. Ezt hozzáadva a kódunkhoz, játszi könnyedséggel tudunk készíteni futás időben PDF dokumentumokat, amelyet aztán az adott platformon - bármely PDF nézegetővel - már küldhetünk is a nyomtatóra. Egy sharpPDF példa:
1 2 3 4 5 6 | |
Látható, hogy a library-t tényleg nagyon egyszerű használatba venni. Én a programban úgy oldottam meg, hogy a konfigurációs XML file tartalmat egy bejegyzést a PDF nézegetőre vonatkozóan:
1
| |
Ezt felhasználva a kódból, az alkalmazást felparaméterezve a generált PDF dokumentummal már látható és nyomtatható is az elkészült anyag:
1 2 3 4 5 6 7 8 | |
Végül így sikerült megoldanom a Mono-ban jelenleg még hiányos nyomtatási függvények mellőzését.