Skip to content

Instantly share code, notes, and snippets.

@TonioGela
Created May 6, 2024 09:41
Show Gist options
  • Save TonioGela/24f315ddeb62ede8464c475036fef94a to your computer and use it in GitHub Desktop.
Save TonioGela/24f315ddeb62ede8464c475036fef94a to your computer and use it in GitHub Desktop.
How to create a simple pdf using a wrapper of a wrapper of a wrapper of a Java library with a strange licensing model
//> using scala 3.3.1
//> using dep com.github.librepdf:openpdf:1.3.33
//> using dep co.fs2::fs2-io::3.9.3
import cats.effect.*
import com.lowagie.text.*
import com.lowagie.text.pdf.PdfWriter
import com.lowagie.text.pdf.PdfPageEventHelper
import fs2.io.file.Files
import fs2.io.file.Path
import com.lowagie.text.pdf.PdfPTable
import com.lowagie.text.pdf.PdfPCell
import scala.concurrent.duration.*
object Foo extends IOApp.Simple:
def run: IO[Unit] =
fs2.io.readOutputStream(2048){os =>
IO {
val document: Document = new Document(PageSize.A4, 36, 36, 65, 36)
val writer = PdfWriter.getInstance(document, os)
writer.setPageEvent(new HeaderAndFooterPageEventHelper())
document.open()
val page1Body: Paragraph = new Paragraph("Page one content.")
page1Body.setAlignment(Element.ALIGN_CENTER)
document.add(page1Body)
document.newPage()
val page2Body: Paragraph = new Paragraph("Page two content.")
page2Body.setAlignment(Element.ALIGN_CENTER)
document.add(page2Body)
document.close()
writer.close()
}
}.through(Files[IO].writeAll(Path("./output.pdf"))).compile.drain.delayBy(1.second).replicateA_(10)
class HeaderAndFooterPageEventHelper extends PdfPageEventHelper {
override def onStartPage(writer: PdfWriter, document: Document): Unit = {
val table: PdfPTable = new PdfPTable(3)
table.setTotalWidth(510)
table.setWidths(Array[Int](38, 36, 36))
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER)
table.getDefaultCell().setPaddingBottom(5)
table.getDefaultCell().setBorder(Rectangle.BOTTOM)
val emptyCell: PdfPCell = new PdfPCell(new Paragraph(""))
emptyCell.setBorder(Rectangle.NO_BORDER)
// Row#1 having 1 empty cell, 1 title cell and empty cell.
table.addCell(emptyCell)
val title: Paragraph = new Paragraph("Grogu Inc.", new Font(Font.COURIER, 20, Font.BOLD))
val titleCell: PdfPCell = new PdfPCell(title)
titleCell.setPaddingBottom(10)
titleCell.setHorizontalAlignment(Element.ALIGN_CENTER)
titleCell.setBorder(Rectangle.NO_BORDER)
table.addCell(titleCell)
table.addCell(emptyCell)
//Row#2 having 3 cells
val cellFont: Font = new Font(Font.HELVETICA, 8)
table.addCell(new Paragraph("Phone Number: 888-999-0000", cellFont))
table.addCell(new Paragraph("Address : 333, Manhattan, New York", cellFont))
table.addCell(new Paragraph("Website : http://grogu-yoda.com", cellFont))
// write the table on PDF
table.writeSelectedRows(0, -1, 34, 828, writer.getDirectContent())
}
override def onEndPage(writer: PdfWriter, document: Document): Unit = {
/* Footer */
val table: PdfPTable = new PdfPTable(2)
table.setTotalWidth(510)
table.setWidths(Array[Int](50,50))
// Magic about default cell - if you add styling to default cell it will apply to all cells except cells added using addCell(PdfPCell) method.
table.getDefaultCell().setPaddingBottom(5)
table.getDefaultCell().setBorder(Rectangle.TOP)
val title: Paragraph = new Paragraph("Grogu Inc.", new Font(Font.HELVETICA, 10))
val titleCell: PdfPCell = new PdfPCell(title)
titleCell.setPaddingTop(4)
titleCell.setHorizontalAlignment(Element.ALIGN_LEFT)
titleCell.setBorder(Rectangle.TOP)
table.addCell(titleCell)
val pageNumberText: Paragraph = new Paragraph("Page "+document.getPageNumber(), new Font(Font.HELVETICA, 10))
val pageNumberCell: PdfPCell = new PdfPCell(pageNumberText)
pageNumberCell.setPaddingTop(4)
pageNumberCell.setHorizontalAlignment(Element.ALIGN_RIGHT)
pageNumberCell.setBorder(Rectangle.TOP)
table.addCell(pageNumberCell)
// write the table on PDF
table.writeSelectedRows(0, -1, 34, 36, writer.getDirectContent())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment