PDF generálás programkódból: így valósíthatod meg Android eszközön
Nem egy szokványos feladat, ha programkódból szeretnénk PDF-ket összeállítani, méghozzá egy Android eszközön keresztül, ám számos olyan helyzet adódhat, amikor a vállalatnak szüksége van erre, azaz egy dinamikusan létrehozott tartalmat rögzíteni, megosztani vagy netalán nyomtatni kell. Ilyen eset például, ha egy számlát vagy bizonylatot kell adni a vásárlónak, és a dinamikusan összeállított PDF-et egy Bluetooth-os nyomtatóval is ki kell nyomtatni, vagy egy logisztikai központban egyedi címkéket kell gyorsan nyomtatni az egyes csomagokra. Milyen módszerek vannak Androidon a UI létrehozására, illetve hogyan lehet az üres PDF objektumot adatokkal feltölteni és elmenteni? Részletek a cikkünkben
Milyen módszerek léteznek Androidon a UI létrehozására?
Bár a PDF generálás nem egy gyakori feladat, viszont nem is magától értetődő. Ha Androidon valamilyen UI felületet szeretnénk összerakni, akkor jelenleg két gyakori megoldás közül választhatunk:
- Az egyik módszer a klasszikus, xml-ben történő UI építés: egy xml fájlban különböző layout-okat és view-kat adunk meg, amelyek segítségével könnyedén tudjuk pozicionálni, és stílussal ellátni az elemeinket.
- A másik lehetőség a Jetpack Compose használata, mely az új, deklaratív módon történő UI építést teszi lehetővé. Ennek használatával még gyorsabban és egyszerűbben alkothatjuk meg a kívánt felhasználói felületet
Hogyan kapcsolódik mindez a PDF létrehozás témaköréhez? Mielőtt rátérnénk erre, előbb vizsgáljuk meg részletesen, hogyan működik az említett két módszer.
Mind az XML alapú felhasználói felület, mind a Jetpack Compose esetében az Android egy üres Canvas-ra rajzolja ki az elemeket, de a módszerek eltérően működnek.
XML alapú UI építés
Az XML definíció során megadott View-k (például Button, TextView, stb.) valójában az Android View osztályából származó objektumok. Amikor a rendszer felolvassa az adott XML fájlt, és megpróbálja a UI-t az XML alapján legyártani, akkor minden egyes View esetében a következő folyamatot hajtja végre.
- Layout Inflating: Létrehozza a megfelelő View objektumokat.
- Rendering: A létrehozott View-k megjelenítési adatai (méret, pozíció, stílus) alapján az Android SDK az egyes View-kat egy Canvas-ra rajzolja ki. Ez a folyamat implicit módon történik.
A UI az XML alapján a különböző View osztályok segítségével felépül, viszont maga a Canvas-ra rajzolás el van rejtve a szemünk elől.
Jetpack Compose
A Jetpack Compose teljesen más elven működik, és a régi View hierarchia helyett a Compose UI elemek egy deklaratív UI-modellt követnek. Compose esetében is a Canvas kerül használatra, de a folyamat és a struktúra eltérő.
- Deklaratív UI: Jetpack Compose-ban a felhasználói felület deklaratívan van megadva, vagyis közvetlenül a komponensek állapota határozza meg, hogy mit jelenít meg. Nincs explicit View hierarchia vagy XML fájl, a felhasználói felületet Composable függvényekkel határozzuk meg.
- Rendering a háttérben: A háttérben a Compose is egy Canvas-ra rajzolja ki az elemeket, de a View rendszerhez képest eltérő módon történik ez a folyamat. A Compose saját renderelő mechanizmussal rendelkezik, és a rendszer optimálisan frissíti a felületet az állapotváltozások alapján.
A Jetpack Compose közvetlenül dolgozik a rajzfelülettel, de az elemek egyedi komponensek. Ezek szintén a Canvas-ra kerülnek kirajzolásra, csak éppen az XML alapú View-któl eltérő modell és rendering mechanizmus mentén.
A két módszer közös jellemzője ez a mágikus Canvas osztály: a nap végén mind a két esetben erre a Canvas-ra rajzolódik rá a felhasználói felület.
Mi is hozzáférhetünk a Canvashoz? Tetszőleges UI felületet hozhatunk létre a segítségével? A válasz: igen! És éppen ezt hívjuk segítségül a PDF fájlunk felépítéséhez.
Mi is pontosan a Canvas?
A Canvas az Android grafikában használt alapvető rajzfelület, amely különféle grafikai elemek, például vonalak, körök, szövegek, képek és egyéb formák megjelenítésére nyújt lehetőséget. Olyan, mint egy "vászon", amire különböző grafikai elemeket "rajzolhatsz".
A Canvas a 2D grafikai API egyik legfontosabb eleme az Androidon.
A Canvas objektum alapvetően egy üres rajzfelület, amelyre a Paint objektum segítségével rajzolhatsz különböző grafikákat és szövegeket. A Canvas magában foglalja a teljes képernyőt, vagy azt a felületet, ahol rajzolni szeretnél. Minden egyes rajzolási művelet után az eredményt megjeleníti a képernyőn.
Rajzolás a Canvas-ra
1. Canvas objektum létrehozása
A Canvas-t általában nem közvetlenül hozzuk létre. A Canvas-t például egy View vagy egy Bitmap objektumhoz társíthatjuk. Amikor egy View-ban rajzolunk, a Canvas automatikusan rendelkezésre áll az onDraw() metóduson belül.
2. Paint objektum használata
A rajzoláshoz szükség van egy Paint objektumra, amely meghatározza a rajzolt elemek megjelenési tulajdonságait (szín, vastagság, stílus, stb.).
3. Rajzolási metódusok
A Canvas számos rajzolási metódust kínál. Ezekkel különféle formákat, képeket, szövegeket lehet megjeleníteni:
- drawLine(): Vonal rajzolása
- drawRect(): Téglalap rajzolása
- drawCircle(): Kör rajzolása
- drawText(): Szöveg rajzolása
- drawBitmap(): Kép megjelenítése
- drawPath(): Egyedi formák rajzolása egy Path segítségével
Egyszerű példa rajzolásra
Nézzük meg, hogyan rajzolhatunk a Canvas-ra. Ehhez létrehozunk egy egyedi View osztályt, és felülírjuk az onDraw() metódust.
A fenti kódból látható, hogy a paint objektum segítségével - amely a stílust határozza meg -, tudunk rajzolni a Canvas-ra, a különböző metódusok segítségével vonalat, kört vagy szöveget.
PDF generálás lépései
Mi a PDF?
A PDF (Portable Document Format) egy széles körben használt fájlformátum, amely dokumentumok, képek, szövegek, grafikonok és más tartalmak tárolására és megosztására szolgál, függetlenül az eszköztől vagy a platformtól. A PDF formátumot az Adobe fejlesztette ki, és azért népszerű, mert bármilyen eszközön ugyanúgy jelenik meg, így garantálja a tartalom konzisztens megjelenítését.
Hogyan lehet Androidon PDF-et létrehozni?
Az Androidon PDF-eket a PdfDocument osztály segítségével hozhatunk létre. A PdfDocument lehetővé teszi oldalak hozzáadását, rajzolását, majd a teljes dokumentum fájlba mentését.
Nézzünk egy egyszerű példát arra hogyan tudunk egy üres PDF objektumot létrehozni és elmenteni.
A fenti kódrészleten az látható, hogy a PdfDocument osztály segítségével létrehozunk egy PDF objektumot, majd ahhoz hozzáadunk egy üres oldalt, és a végén elmentjük egy fájlba a saveIntoFile() metódus segítségével. Az is látható továbbá hogyan tudunk hozzájutni az üres Canvas-hoz, amelyre kirajzoljuk majd azokat az elemeket, amelyeket meg szeretnénk jeleníteni a dokumentumban.
Gyakorlati példa egy címkeszerű elrendezés létrehozására
Most pedig nézzünk meg egy egyszerű példát arra, hogyan tudunk néhány általános elemet kirajzolni, mint például egy Bitmap-et vagy különböző szövegeket. Arra érdemes figyelni, hogy itt nem tudunk olyan könnyedén pozícionálni elemeket, mint például egy xml-ben. Ha középre szeretnénk igazítani egy elemet, akkor bizony pontos koordinátákat kell megadnunk, nem elegendő annyit megadni, hogy “gravity=center”.
A fenti kódrészlet egy olyan pdf dokumentumot hoz létre, amelynek jobb oldalán egy QR kód van, a QR kódtól balra egy title, a QR kód alatt pedig - a függvénynek átadott data listában szereplő adatoknak megfelelően - egy-egy kulcs érték pár.
Most pedig nézzük át tüzetesebben a fontosabb részeket.
A metódus első részében felolvasunk néhány resource-t és kiszámoljuk a pdf méreteit.
Ezután a következő kódrészlettel kirajzoljuk a QR kódot. A QR kód generálásához a “com.journeyapps:zxing-android-embedded” könyvtárat használjuk.
Ahogy a fenti kódrészletben is látszik, meg kell adnunk az x és az y koordinátákat. Ahhoz, hogy az x tengelyen eltoljuk teljesen bal oldalra a QR kódot, a Canvas szélességéből levonjuk a QR kód bitmap szélességét. Az y tengelyen ezzel szemben nem szeretnénk eltolni, ezért ott 0f-et adunk meg, ami azt eredményezni, hogy a QR kód a jobb felső sarokba kerül.
Következik a cím kiírása:
Látható, hogy a Paint objektum segítségével formázhatjuk a szöveget. Itt különösebb pozicionálás nem történik, a cím szövegünk a bal felső sarokba fog kerülni.
Ezután pedig a QR kód alá kirajzoljuk a data listában lévő kulcs érték párokat, sorról sorra.
Itt a currentVerticalPosition növelésével kezdünk. Ennek a változónak a segítségével tudjuk nyomon követni, hogy az y tengelyen éppen hol járunk. Ezután létrehozzuk a paint objektumokat, amelyek segítségével megadjuk a szövegek formázását. Majd a data listát bejárva kirajzoljuk a kulcs érték párokat a következő módon: a kulcsot bal oldalra, az értéket pedig jobb oldalra igazítva. A jobb oldalra igazítás hasonlóan történik, mint a QR kód esetében: a szöveg szélességének a canvas szélességéből történő kivonásával tudjuk megadni.
Ha horizontálisan középre szeretnénk igazítani egy szöveget, akkor azt úgy tudjuk megtenni, hogy a Canvas szélességéből kivonjuk a szöveg szélességét, majd a kapott értéket elosztjuk kettővel. Így megkapjuk a középre igazításhoz szükséges x koordinátát.
Ismerd meg hogyan támogatta a Zebra ökoszisztéma az app fejlesztéseinket cimkenyomtatás, QR kód beolvasás, Kiosk mód, illetve offline működés esetén!