add object drawer support
This commit is contained in:
parent
d9e61030e5
commit
797232f2a6
|
@ -2,6 +2,7 @@
|
|||
(:require
|
||||
[clojure.java.io :as io]
|
||||
[hiccup.page :as h]
|
||||
[clj-htmltopdf.objects :as obj]
|
||||
[clj-htmltopdf.options :as o]
|
||||
[clj-htmltopdf.watermark :as w])
|
||||
(:import
|
||||
|
@ -45,15 +46,20 @@
|
|||
html-doc))
|
||||
|
||||
(defn write-pdf!
|
||||
^InputStream [^Document html-doc ^String base-uri]
|
||||
(let [builder (PdfRendererBuilder.)]
|
||||
^InputStream [^Document html-doc options]
|
||||
(let [builder (PdfRendererBuilder.)
|
||||
base-uri (o/->base-uri options)]
|
||||
(obj/set-object-drawer-factory builder options)
|
||||
(.withW3cDocument builder (DOMBuilder/jsoup2DOM html-doc) base-uri)
|
||||
(let [piped-in (PipedInputStream.)
|
||||
piped-out (PipedOutputStream. piped-in)]
|
||||
(future
|
||||
(with-open [os piped-out]
|
||||
(.toStream builder os)
|
||||
(.run builder)))
|
||||
(try
|
||||
(with-open [os piped-out]
|
||||
(.toStream builder os)
|
||||
(.run builder))
|
||||
(catch Exception ex
|
||||
(println "Exception while rendering PDF" ex))))
|
||||
piped-in)))
|
||||
|
||||
(defn ->pdf
|
||||
|
@ -61,7 +67,7 @@
|
|||
(let [options (o/get-final-options options)
|
||||
html-doc (prepare-html in options)]
|
||||
(configure-logging! options)
|
||||
(let [pdf (write-pdf! html-doc (o/->base-uri options))
|
||||
(let [pdf (write-pdf! html-doc options)
|
||||
out (->output-stream out)]
|
||||
(if (:watermark options)
|
||||
(w/write-watermark! pdf out options)
|
||||
|
|
47
src/clj_htmltopdf/objects.clj
Normal file
47
src/clj_htmltopdf/objects.clj
Normal file
|
@ -0,0 +1,47 @@
|
|||
(ns clj-htmltopdf.objects
|
||||
(:require
|
||||
[clojure.string :as string])
|
||||
(:import
|
||||
[com.openhtmltopdf.extend FSObjectDrawer FSObjectDrawerFactory OutputDevice OutputDeviceGraphicsDrawer]
|
||||
[com.openhtmltopdf.pdfboxout PdfRendererBuilder]
|
||||
[org.w3c.dom Element NamedNodeMap]))
|
||||
|
||||
(defn element-attrs->map
|
||||
[^Element element]
|
||||
(let [attributes (.getAttributes element)]
|
||||
(reduce
|
||||
(fn [m idx]
|
||||
(let [node (.item attributes (int idx))
|
||||
name (.getNodeName node)
|
||||
value (.getNodeValue node)]
|
||||
(assoc m (keyword name) value)))
|
||||
{}
|
||||
(range (.getLength attributes)))))
|
||||
|
||||
(defn ->object-drawer-by-id
|
||||
^FSObjectDrawer [f]
|
||||
(reify FSObjectDrawer
|
||||
(drawObject [_ element x y width height output-device rendering-context dots-per-pixel]
|
||||
(.drawWithGraphics
|
||||
^OutputDevice output-device
|
||||
(float x)
|
||||
(float y)
|
||||
(float (/ width dots-per-pixel))
|
||||
(float (/ height dots-per-pixel))
|
||||
(reify OutputDeviceGraphicsDrawer
|
||||
(render [_ graphics2d]
|
||||
(f (element-attrs->map element) graphics2d)))))))
|
||||
|
||||
(defn ->object-drawer-by-id-factory
|
||||
^FSObjectDrawerFactory [options]
|
||||
(reify FSObjectDrawerFactory
|
||||
(^FSObjectDrawer createDrawer [_ ^Element element]
|
||||
(if (.hasAttribute element "id")
|
||||
(let [element-id (.getAttribute element "id")]
|
||||
(if-let [f (get-in options [:objects :by-id element-id])]
|
||||
(->object-drawer-by-id f)))))))
|
||||
|
||||
(defn set-object-drawer-factory
|
||||
[^PdfRendererBuilder builder options]
|
||||
(let [factory (->object-drawer-by-id-factory options)]
|
||||
(.useObjectDrawerFactory builder factory)))
|
Loading…
Reference in a new issue