3

I'm using clj-pdf to generate pdf files. As the README file suggests, the library provides some rudimentary templating options.

For example, given a vector of maps, such as:

(def employees
  [{:country "Germany",
    :place "Nuremberg",
    :occupation "Engineer",
    :name "Neil Chetty"}
   {:country "Germany",
    :place "Ulm",
    :occupation "Engineer",
    :name "Vera Ellison"}])

and a template

(def employee-template
  (template
    [:paragraph
     [:heading $name]
     [:chunk {:style :bold} "occupation: "] $occupation "\n"
     [:chunk {:style :bold} "place: "] $place "\n"
     [:chunk {:style :bold} "country: "] $country
     [:spacer]]))

The following output will be produced:

(employee-template employees)

([:paragraph [:heading "Neil Chetty"] 
  [:chunk {:style :bold} "occupation: "] "Engineer" "\n" 
  [:chunk {:style :bold} "place: "] "Nuremberg" "\n" 
  [:chunk {:style :bold} "country: "] "Germany" [:spacer]] 
 [:paragraph [:heading "Vera Ellison"] 
  [:chunk {:style :bold} "occupation: "] "Engineer" "\n" 
  [:chunk {:style :bold} "place: "] "Ulm" "\n" 
  [:chunk {:style :bold} "country: "] "Germany" [:spacer]])

However, I'm wondering how to use this template in pdf function. When I use

(pdf
  [[:heading "Heading 1"]
   [:table
    {:width 100  :border false  :cell-border false  :widths [30 70]  :offset 35}
    [[:cell {:align :right}
      (employee-template employees)]
     [:cell "dummy"]]]
   [:heading "Heading 2"]]
  "output.pdf")

I got a invalid tag exception.

If I change (employee-template employees) to (first (employee-template employees)), it works however not as I expect. What is the correct way to use a template?

DANG Fan
  • 854
  • 11
  • 21
  • i copy and pasted your code and it run without modification and it runs. – KobbyPemson May 04 '14 at 18:21
  • @KobbyPemson Thanks for pointing out. I've updated the question now it can raise an exception. – DANG Fan May 05 '14 at 01:04
  • In the README for clj-pdf, the examples of using the `pdf` function all have `{}` (an empty map of optional metadata) as the first argument. Could the issue be that you left that out? – Dave Yarwood May 05 '14 at 14:52
  • (to clarify, it's not actually the first argument, but rather the first element of the vector that you provide as the first argument to `pdf`) – Dave Yarwood May 05 '14 at 14:57
  • @DaveYarwood The empty map `{}` can be omitted which means using the default settings. – DANG Fan May 06 '14 at 11:31

2 Answers2

1

This works. Generate a new cell for each employee.

(pdf
  [[:heading "Heading 1"]
   [:table {:width 100  :border false  :cell-border false :widths [30 70]  :offset 35}
    (for [e (employee-template employees)]
      [:cell {:align :right} e])]
   [:heading "Heading 2"]]
  "output.pdf")
KobbyPemson
  • 2,519
  • 1
  • 18
  • 33
0

Use apply and concat maybe?

(pdf
    (apply concat
           [[:heading "Heading 1"]]
           (employee-template employees)
           [[:heading "Heading 2"]])
    "output.pdf")

I think there should be a better choice to do this,the concat may not be efficient.

user950101
  • 11
  • 3
  • Why do you think the concat will be inefficient? The horror case would be a billion employees, but as concat simply creates a seq that iterates through the underlying collections I'm not imagining it to be especially horrid. – pete23 May 04 '14 at 18:24