Skip to content

Commit

Permalink
Merge pull request #23 from hhandoko/feature/switch_to_openpdf
Browse files Browse the repository at this point in the history
Feature - Switch to OpenPDF
  • Loading branch information
hhandoko authored Jun 24, 2018
2 parents bb2387e + 678df47 commit 63f4755
Show file tree
Hide file tree
Showing 22 changed files with 91 additions and 50 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
[![Master Build Status](https://travis-ci.org/hhandoko/play2-scala-pdf.svg?branch=master)](https://travis-ci.org/hhandoko/play2-scala-pdf)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hhandoko/play2-scala-pdf_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.hhandoko/play2-scala-pdf_2.12)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hhandoko/play26-scala-pdf_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.hhandoko/play26-scala-pdf_2.12)

# Play [2.4 | 2.5 | 2.6] PDF module

`play2-scala-pdf` is a Play Framework module to help generate PDF documents dynamically from Play Framework web application.

It simply renders Play Framework HTML and CSS-based view templates to PDF via [Flying Saucer library], which uses older, open-source version of iText for PDF generation.
It simply renders Play Framework HTML and CSS-based view templates to PDF via [Flying Saucer library], which uses [OpenPDF], an open-source LGPL and MPL version of an older fork of iText for PDF generation.

### Supported Play Framework and Scala Versions

Expand All @@ -26,11 +26,21 @@ If you are using Play Framework Java, check out [https://github.com/innoveit/pla

## Installation

Create a PDF generator factory method in your application's Guice module:
``` scala
@Provides
def providePdfGenerator(): PdfGenerator = {
val pdfGen = new PdfGenerator()
pdfGen.loadLocalFonts(Seq("fonts/opensans-regular.ttf"))
pdfGen
}
```

Currently, the module is hosted at Maven Central Repository. Include the following lines in ```build.sbt```, then reload SBT to resolve and enable the module:
``` scala
libraryDependencies ++= Seq(
...
"com.hhandoko" %% "play2-scala-pdf" % "3.0.0.P26" // Use `3.0.0.P25` for Play 2.5.x apps or `3.0.0.P24 for Play 2.4.x apps
"com.hhandoko" %% "play26-scala-pdf" % "4.0.0" // Use `play25-scala-pdf` for Play 2.5.x apps or `play24-scala-pdf` for Play 2.4.x apps
)
```

Expand Down Expand Up @@ -144,5 +154,6 @@ https://github.com/hhandoko/play2-scala-pdf/releases
[fork-and-pull]: https://help.github.com/articles/using-pull-requests
[LICENSE]: LICENSE
[Lightbend]: https://www.lightbend.com/company
[OpenPDF]: https://github.com/LibrePDF/OpenPDF
[Open Sans Google Fonts]: https://fonts.google.com/specimen/Open+Sans
[Steve Matteson]: https://twitter.com/@SteveMatteson1
1 change: 1 addition & 0 deletions VERSION.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4.0.0-SNAPSHOT
4 changes: 2 additions & 2 deletions examples/play24-example/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
name := """play2-scala-pdf-example"""
name := """play24-scala-pdf-example"""

version := "1.0.0.P24"
version := "1.0.0"

scalaVersion := "2.11.12"

Expand Down
4 changes: 2 additions & 2 deletions examples/play25-example/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
name := """play2-scala-pdf-example"""
name := """play25-scala-pdf-example"""

version := "1.0.0.P25"
version := "1.0.0"

scalaVersion := "2.11.12"

Expand Down
8 changes: 4 additions & 4 deletions examples/play26-example/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
name := """play2-scala-pdf-example"""
name := """play26-scala-pdf-example"""

version := "1.0.0.P26"
version := "1.0.0"

scalaVersion := "2.12.4"
scalaVersion := "2.12.6"

crossScalaVersions := Seq("2.11.12", "2.12.4")
crossScalaVersions := Seq("2.11.12", "2.12.6")

libraryDependencies ++= Seq(
guice,
Expand Down
2 changes: 1 addition & 1 deletion examples/play26-example/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Play Framework plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.12")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.15")
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import java.io._
import scala.collection.mutable.ArrayBuffer

import com.google.inject.Singleton
import com.itextpdf.text.pdf.BaseFont
import com.lowagie.text.pdf.BaseFont
import nu.validator.htmlparser.dom.HtmlDocumentBuilder
import org.apache.commons.io.{FilenameUtils, IOUtils}
import org.w3c.tidy.Tidy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ package com.hhandoko.play.pdf

import java.io._

import com.itextpdf.text.Image
import com.lowagie.text.Image
import org.xhtmlrenderer.pdf.{ITextFSImage, ITextOutputDevice, ITextUserAgent}
import org.xhtmlrenderer.resource.{CSSResource, ImageResource, XMLResource}

Expand Down
10 changes: 7 additions & 3 deletions modules/play24/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
name := """play2-scala-pdf"""
import scala.io.Source

name := """play24-scala-pdf"""

organization := "com.hhandoko"

version := "3.0.1.P24-SNAPSHOT"
version := Source.fromFile("../../VERSION.txt").mkString.trim

scalaVersion := "2.11.12"

Expand All @@ -43,9 +45,11 @@ libraryDependencies ++= Seq(
// - http://jtidy.sourceforge.net/
// - https://github.com/flyingsaucerproject/flyingsaucer
// - https://about.validator.nu/htmlparser/
// - https://jsoup.org/
"net.sf.jtidy" % "jtidy" % "r938",
"org.xhtmlrenderer" % "flying-saucer-pdf-itext5" % "9.1.12",
"org.xhtmlrenderer" % "flying-saucer-pdf-openpdf" % "9.1.12",
"nu.validator.htmlparser" % "htmlparser" % "1.4",
"org.jsoup" % "jsoup" % "1.11.3" % Test,

// ScalaTest + Play plugin
// - http://www.scalatest.org/plus/play
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ package com.hhandoko.play.pdf
import java.io.InputStream
import scala.io.Source

import com.itextpdf.text.pdf.PdfReader
import com.itextpdf.text.pdf.parser.PdfTextExtractor
import com.lowagie.text.pdf.PdfReader
import com.lowagie.text.pdf.parser.PdfTextExtractor
import org.jsoup.Jsoup
import org.scalatestplus.play.{OneAppPerTest, PlaySpec}

import play.twirl.api.Html
Expand All @@ -42,50 +43,55 @@ class PdfGeneratorSpec extends PlaySpec with OneAppPerTest {
def htmlStream: Option[InputStream] = app.resourceAsStream("example.html")
def htmlString: String = htmlStream.fold("") { Source.fromInputStream(_).getLines().mkString("\n") }
def html: Html = Html(htmlString)
val gen = new PdfGenerator()
def clean(html: String): String = Jsoup.parse(html).text()

"PdfGenerator" should {

val author = "play2-scala-pdf Contributors"
val title = "`play2-scala-pdf` HTML to PDF example"
val heading = "Hello, world!"
val gen = new PdfGenerator()

"be able to create PDF given HTML string" in {
val pdf = gen.toBytes(htmlString, BASE_URL, Nil)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

"be able to create PDF given HTML string and external font" in {
val fonts = Seq("opensans-regular.ttf")
val pdf = gen.toBytes(htmlString, BASE_URL, fonts)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

"be able to create PDF given Twirl HTML" in {
val pdf = gen.toBytes(html, BASE_URL, Nil)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

"be able to create PDF given Twirl HTML and external font" in {
val fonts = Seq("opensans-regular.ttf")
val pdf = gen.toBytes(html, BASE_URL, fonts)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import java.io._
import scala.collection.mutable.ArrayBuffer

import com.google.inject.Singleton
import com.itextpdf.text.pdf.BaseFont
import com.lowagie.text.pdf.BaseFont
import nu.validator.htmlparser.dom.HtmlDocumentBuilder
import org.apache.commons.io.{FilenameUtils, IOUtils}
import org.w3c.tidy.Tidy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ package com.hhandoko.play.pdf

import java.io._

import com.itextpdf.text.Image
import com.lowagie.text.Image
import org.xhtmlrenderer.pdf.{ITextFSImage, ITextOutputDevice, ITextUserAgent}
import org.xhtmlrenderer.resource.{CSSResource, ImageResource, XMLResource}

Expand Down
10 changes: 7 additions & 3 deletions modules/play25/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
name := """play2-scala-pdf"""
import scala.io.Source

name := """play25-scala-pdf"""

organization := "com.hhandoko"

version := "3.0.1.P25-SNAPSHOT"
version := Source.fromFile("../../VERSION.txt").mkString.trim

scalaVersion := "2.11.12"

Expand All @@ -43,9 +45,11 @@ libraryDependencies ++= Seq(
// - http://jtidy.sourceforge.net/
// - https://github.com/flyingsaucerproject/flyingsaucer
// - https://about.validator.nu/htmlparser/
// - https://jsoup.org/
"net.sf.jtidy" % "jtidy" % "r938",
"org.xhtmlrenderer" % "flying-saucer-pdf-itext5" % "9.1.12",
"org.xhtmlrenderer" % "flying-saucer-pdf-openpdf" % "9.1.12",
"nu.validator.htmlparser" % "htmlparser" % "1.4",
"org.jsoup" % "jsoup" % "1.11.3" % Test,

// ScalaTest + Play plugin
// - http://www.scalatest.org/plus/play
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ package com.hhandoko.play.pdf
import java.io.InputStream
import scala.io.Source

import com.itextpdf.text.pdf.PdfReader
import com.itextpdf.text.pdf.parser.PdfTextExtractor
import com.lowagie.text.pdf.PdfReader
import com.lowagie.text.pdf.parser.PdfTextExtractor
import org.jsoup.Jsoup
import org.scalatestplus.play.{OneAppPerTest, PlaySpec}

import play.api.Environment
Expand All @@ -45,6 +46,7 @@ class PdfGeneratorSpec extends PlaySpec with OneAppPerTest {
def htmlString: String = htmlStream.fold("") { Source.fromInputStream(_).getLines().mkString("\n") }
def html: Html = Html(htmlString)
def gen = new PdfGenerator(env)
def clean(html: String): String = Jsoup.parse(html).text()

"PdfGenerator" should {

Expand All @@ -55,39 +57,43 @@ class PdfGeneratorSpec extends PlaySpec with OneAppPerTest {
"be able to create PDF given HTML string" in {
val pdf = gen.toBytes(htmlString, BASE_URL, Nil)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

"be able to create PDF given HTML string and external font" in {
val fonts = Seq("opensans-regular.ttf")
val pdf = gen.toBytes(htmlString, BASE_URL, fonts)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

"be able to create PDF given Twirl HTML" in {
val pdf = gen.toBytes(html, BASE_URL, Nil)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

"be able to create PDF given Twirl HTML and external font" in {
val fonts = Seq("opensans-regular.ttf")
val pdf = gen.toBytes(html, BASE_URL, fonts)
val reader = new PdfReader(pdf)
val extractor = new PdfTextExtractor(reader)

assert(reader.getInfo.get("Author") === author)
assert(reader.getInfo.get("Title") === title)
assert(PdfTextExtractor.getTextFromPage(reader, 1).contains(heading))
assert(clean(extractor.getTextFromPage(1)).contains(heading))
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import java.io._
import scala.collection.mutable.ArrayBuffer

import com.google.inject.Singleton
import com.itextpdf.text.pdf.BaseFont
import com.lowagie.text.pdf.BaseFont
import nu.validator.htmlparser.dom.HtmlDocumentBuilder
import org.apache.commons.io.{FilenameUtils, IOUtils}
import org.w3c.tidy.Tidy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ package com.hhandoko.play.pdf

import java.io._

import com.itextpdf.text.Image
import com.lowagie.text.Image
import org.xhtmlrenderer.pdf.{ITextFSImage, ITextOutputDevice, ITextUserAgent}
import org.xhtmlrenderer.resource.{CSSResource, ImageResource, XMLResource}

Expand Down
14 changes: 9 additions & 5 deletions modules/play26/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
name := """play2-scala-pdf"""
import scala.io.Source

name := """play26-scala-pdf"""

organization := "com.hhandoko"

version := "3.0.1.P26-SNAPSHOT"
version := Source.fromFile("../../VERSION.txt").mkString.trim

scalaVersion := "2.12.4"
scalaVersion := "2.12.6"

crossScalaVersions := Seq("2.11.12", "2.12.4")
crossScalaVersions := Seq("2.11.12", "2.12.6")

libraryDependencies ++= Seq(
guice,
Expand All @@ -45,9 +47,11 @@ libraryDependencies ++= Seq(
// - http://jtidy.sourceforge.net/
// - https://github.com/flyingsaucerproject/flyingsaucer
// - https://about.validator.nu/htmlparser/
// - https://jsoup.org/
"net.sf.jtidy" % "jtidy" % "r938",
"org.xhtmlrenderer" % "flying-saucer-pdf-itext5" % "9.1.12",
"org.xhtmlrenderer" % "flying-saucer-pdf-openpdf" % "9.1.12",
"nu.validator.htmlparser" % "htmlparser" % "1.4",
"org.jsoup" % "jsoup" % "1.11.3" % Test,

// ScalaTest + Play plugin
// - http://www.scalatest.org/plus/play
Expand Down
2 changes: 1 addition & 1 deletion modules/play26/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Play Framework plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.12")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.15")

// Maven publishing-specific
// ~~~~~
Expand Down
Loading

0 comments on commit 63f4755

Please sign in to comment.