|
6 | 6 |
|
7 | 7 | ===== Problem
|
8 | 8 |
|
9 |
| -Given some text, you need to generate a formatted PDF report |
| 9 | +Given a collection of maps, such as those returned by +clojure.java.jdbc+ queries, you need to generate a formatted PDF report. |
10 | 10 |
|
11 | 11 | ===== Solution
|
12 | 12 |
|
13 |
| -Use the +clj-pdf+ library to easily create PDF documents. |
14 |
| -To create a PDF call +clj-pdf.core/pdf+ with a vector containing a map of metadata followed by the document content. |
15 |
| -The content can consist of strings, vectors or collections of vectors. For example, a simple document might look as follows: |
| 13 | +Use the +clj-pdf+ library to easily create the report. Say we have a vector containing the employee records as seen below: |
| 14 | + |
| 15 | +---- |
| 16 | +;;data |
| 17 | +(def employees |
| 18 | + [{:country "Germany", |
| 19 | + :place "Nuremberg", |
| 20 | + :occupation "Engineer", |
| 21 | + :name "Neil Chetty"} |
| 22 | + {:country "Germany", |
| 23 | + :place "Ulm", |
| 24 | + :occupation "Engineer", |
| 25 | + :name "Vera Ellison"}]) |
| 26 | +---- |
| 27 | + |
| 28 | +We first create a template for rendering each record using the +clj-pdf.core/template+ macro: |
| 29 | + |
| 30 | +---- |
| 31 | +;;template |
| 32 | +(def employee-template |
| 33 | + (template |
| 34 | + [:paragraph |
| 35 | + [:heading (.toUpperCase $name)] |
| 36 | + [:chunk {:style :bold} "occupation: "] $occupation "\n" |
| 37 | + [:chunk {:style :bold} "place: "] $place "\n" |
| 38 | + [:chunk {:style :bold} "country: "] $country |
| 39 | + [:spacer]])) |
| 40 | +---- |
| 41 | + |
| 42 | +The +$+ in the template above is used to indicate the anchors for the dynamic content. Note that we can post-process the values of the anchors as we're doing with the +$name+. |
| 43 | + |
| 44 | +Calling the template with the employee data produces the following output: |
| 45 | + |
| 46 | +---- |
| 47 | +(employee-template employees) |
| 48 | +
|
| 49 | +([:paragraph [:heading "Neil Chetty"] |
| 50 | + [:chunk {:style :bold} "occupation: "] "Engineer" "\n" |
| 51 | + [:chunk {:style :bold} "place: "] "Nuremberg" "\n" |
| 52 | + [:chunk {:style :bold} "country: "] "Germany" [:spacer]] |
| 53 | +[:paragraph [:heading "Vera Ellison"] |
| 54 | + [:chunk {:style :bold} "occupation: "] "Engineer" "\n" |
| 55 | + [:chunk {:style :bold} "place: "] "Ulm" "\n" |
| 56 | + [:chunk {:style :bold} "country: "] "Germany" [:spacer]]) |
| 57 | +---- |
| 58 | + |
| 59 | +We can now call +clj-pdf.core/pdf+ to create the PDF using this data: |
| 60 | + |
| 61 | +---- |
| 62 | +(pdf [{:title "Employee Table"} (employee-template employees)] "employees.pdf") |
| 63 | +---- |
| 64 | + |
| 65 | +===== Discussion |
| 66 | + |
| 67 | +The +clj-pdf+ library is built on top of +iText+ and +JFreeChart+ libraries. The syntax is inspired by the popular +Hiccup+ HTML templating engine. |
| 68 | + |
| 69 | +A document is represented by a vector containing a map of metadata followed by the content. The content can in turn consist of strings, vectors or collections of vectors. For example, a simple document might look as follows: |
16 | 70 |
|
17 | 71 | ----
|
18 | 72 | (pdf [{:title "My Document"} "some text"] "document.pdf")
|
@@ -49,6 +103,12 @@ Elements can have optional styling metadata
|
49 | 103 |
|
50 | 104 | ----
|
51 | 105 | [:paragraph {:style :bold} "this text is bold"]
|
| 106 | +
|
| 107 | +[:chunk {:style :bold |
| 108 | + :size 18 |
| 109 | + :family :helvetica |
| 110 | + :color [0 234 123]} |
| 111 | + "some large green text"] |
52 | 112 | ----
|
53 | 113 |
|
54 | 114 | The content of each element can consist of other elements, any style applied to the parent element
|
@@ -104,62 +164,3 @@ The library also has support for bar charts, pie charts, line series and time se
|
104 | 164 | :y-label "progress"}
|
105 | 165 | ["Occurances" ["01/11" 200] ["02/12" 400] ["05/12" 350] ["11/13" 600]]]
|
106 | 166 | ----
|
107 |
| - |
108 |
| -When you have data in a collection of maps, such as if you queried it using +clojure.java.jdbc+ then |
109 |
| -you can use the +clj-pdf.core/template+ macro to format it: |
110 |
| - |
111 |
| ----- |
112 |
| -;;data |
113 |
| -(def employees |
114 |
| - [{:country "Germany", |
115 |
| - :place "Nuremberg", |
116 |
| - :occupation "Engineer", |
117 |
| - :name "Neil Chetty"} |
118 |
| - {:country "Germany", |
119 |
| - :place "Ulm", |
120 |
| - :occupation "Engineer", |
121 |
| - :name "Vera Ellison"}]) |
122 |
| ----- |
123 |
| -The +$+ is used to indicate the anchors in the template: |
124 |
| ----- |
125 |
| -;;template |
126 |
| -(def employee-template |
127 |
| - (template |
128 |
| - [:paragraph |
129 |
| - [:heading $name] |
130 |
| - [:chunk {:style :bold} "occupation: "] $occupation "\n" |
131 |
| - [:chunk {:style :bold} "place: "] $place "\n" |
132 |
| - [:chunk {:style :bold} "country: "] $country |
133 |
| - [:spacer]])) |
134 |
| ----- |
135 |
| - |
136 |
| -calling the template with the employee data produces the following output |
137 |
| ----- |
138 |
| -(employee-template employees) |
139 |
| -
|
140 |
| -([:paragraph [:heading "Neil Chetty"] |
141 |
| - [:chunk {:style :bold} "occupation: "] "Engineer" "\n" |
142 |
| - [:chunk {:style :bold} "place: "] "Nuremberg" "\n" |
143 |
| - [:chunk {:style :bold} "country: "] "Germany" [:spacer]] |
144 |
| -[:paragraph [:heading "Vera Ellison"] |
145 |
| - [:chunk {:style :bold} "occupation: "] "Engineer" "\n" |
146 |
| - [:chunk {:style :bold} "place: "] "Ulm" "\n" |
147 |
| - [:chunk {:style :bold} "country: "] "Germany" [:spacer]]) |
148 |
| ----- |
149 |
| - |
150 |
| -The anchors can also be post processed |
151 |
| ----- |
152 |
| -(def employee-template |
153 |
| - (template |
154 |
| - [:paragraph |
155 |
| - [:heading (if $name (.toUpperCase $name))] |
156 |
| - [:chunk {:style :bold} "occupation: "] $occupation "\n" |
157 |
| - [:chunk {:style :bold} "place: "] $place "\n" |
158 |
| - [:chunk {:style :bold} "country: "] $country |
159 |
| - [:spacer]])) |
160 |
| ----- |
161 |
| - |
162 |
| -===== Discussion |
163 |
| - |
164 |
| -The +clj-pdf+ library is built on top of +iText+ and +JFreeChart+ libraries. The syntax is inspired by the popular +Hiccup+ HTML templating engine. |
165 |
| - |
|
0 commit comments