Hey, whats the easiest way in kotlin to generate s...
# compose-desktop
m
Hey, whats the easiest way in kotlin to generate something like a pdf export? In particular, I want to generate a pdf for a weekly duty schedule, which has a pretty complicated layout.
m
You can use pdfbox, it's not going to be easy, especially if the pdf is complex as you mentioned.
m
So there really isn't a nice and simple solution? 😅
m
Check maybe it will make the task easier: https://github.com/timrs2998/pdf-builder
But in general you will have a canvas and you need to draw everything on that canvas. You can make things easier with static positions and sizes since the PDF page size is fixed.
m
Oh my god… seems to be very painful to do 😭
Is there a way to „draw a composable“ onto a pdf? 😅 I already implemented this complex ladout as a composable so it would make my life a lot easier 😂
m
Haha I had the same use case and I'm actually thinking of building a Compose PDF library. You can convert the composable into an image and create a pdf using that image if it's ok for you to have just an image in your pdf.
m
I'll have a look into it. 😅 I'll let you know 👍
🤞 1
e
skia has a PDF backend
m
?
e
it's not exposed in skiko (the Kotlin binding to skia, which Compose uses for all drawing) but SkPdf outputs pdf
c
I've used openhtmltopdf with some success in the past, converting HTML with some basic CSS styling to PDFs https://github.com/danfickle/openhtmltopdf
z
If you're wanting to display a pdf in compose you can use this library I made https://github.com/zt64/compose-pdf
K 2
🎉 3
K 2
m
@zt If only it would support iOS as well 😢
m
I've worked on a compose-pdf renderer backed by PDFBox that renders PDF content on Compose Canvas instead of just rendering images, which improves performance and memory consumption and you can zoom-in without losing quality. I'm thinking of publishing it as a library, but it's a desktop-only solution for now.
m
That would be very interesting to look at 😉. On desktop I currently also use PDFBox but render it into an image first. On Android I am using com.tom-roush:pdfbox-android although not for rendering. For rendering I am using the native PdfRenderer on Android because it is faster.
e
rendering pdfs is the opposite of what the original question asked though
😅 3
😆 2
m
Honestly, Compose is great but I'd just do it with JavaFX. You can print nodes, and from the print dialog selecting "Print to PDF" will do the trick. JavaFX also has the sophisticated table views you'd need to create the layout appropriately.
(If you don't want a dialog you can just search the printer list for the built in "print to pdf" printer and use that without bringing up the selector)
m
That's how the layout should look like. It's a pretty basic schedule but every employee should have its own column per weekday, if you understand what I mean... this is, what makes creating a pdf really really hard. I've been trying this for 5 hours straight now, but it's REALLY painful. 😅
m
Well if it's a calendar you could use https://dlsc.com/products/calendarfx/ and print it
m
JavaFX?
m
Yeah
You can use both in the same process
m
really?
How this? 😂
m
Sure. You can even embed JavaFX/Compose together if you go via the Swing interop, though there are a lot of caveats. It's not needed just for printing though, as that doesn't require a window or to be on the main event thread.
m
So I can just add this calendarfx library and use it without a javafx app?
m
I think it should work. I've not tried it, but in theory it can be done yes.
For development you will probably want to see what is about to be printed of course. So might make sense to start JavaFX up in a separate thread and display a window until you get it right.
e
https://github.com/JetBrains/compose-multiplatform/issues/17 there's been issues before so it's not a given that it'll work… but hopefully
m
Well, I wouldn't try and do anything fancy. You don't need to use javafx coroutines if all you want to do is generate a PDF/print. Just do it all blocking in a real thread.
m
How do I include javafx in gradle? Do I also need the jfx plugin in this casE?
m
There are instructions on openjfx.org, I can't give you a full JavaFX tutorial here unfortunately.
m
Okey
Sorry but how am I supposed to implement this logic in my program? I inserted this one (for now) in my main method just to test, but it doesn't work
Copy code
Platform.startup {
        val printerJob = PrinterJob.createPrinterJob()

        val view = CalendarView()

        val c1 = Calendar<Any>("EMP1")
        val c2 = Calendar<Any>("EMP2")

        val source = CalendarSource("asd")
        source.calendars.addAll(c1, c2)
        view.requestedTime = LocalTime.now()

        printerJob.printPage(view)
    }
213 Views