Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Compojureベースのウェブアプリケーションでデータベースから読み込んだ内容をPDF出力する。
(ns try-itext-compojure.handler
(:require [ring.util.response :as response]
[compojure.core :refer [defroutes GET]]
[compojure.handler :as handler]
[compojure.route :as route]
[korma.db :refer [defdb sqlite3]]
[korma.core :as korma])
(:import [com.itextpdf.text
Document PageSize Paragraph Font]
[com.itextpdf.text.pdf
PdfWriter BaseFont PdfPTable PdfPCell]
[java.io ByteArrayOutputStream ByteArrayInputStream]))
;データベース定義
(defdb db (sqlite3
{:db "db/try-itext.sqlite3"}))
;employeesテーブルに対応するEntity定義
(korma/defentity employees)
;PDFで使用するフォント
(def font (Font. (BaseFont/createFont
"HeiseiKakuGo-W5"
"UniJIS-UCS2-H"
BaseFont/NOT_EMBEDDED)))
;PDFテーブルのセルを返す
(defn cell [content]
(PdfPCell. (Paragraph. content font)))
;PDFテーブルに行追加
(defn add-row [table c1 c2]
(doto table
(.addCell (cell c1))
(.addCell (cell c2))))
;PDFテーブル取得
(defn get-table []
(let [table (PdfPTable. 2)]
(add-row table "ID" "名前")
;DBから取得したデータを追加
(doseq [row (korma/select employees)]
(add-row table (str (:id row)) (:name row)))
table))
;PDFデータをバイト列で取得
(defn get-pdf-data []
(let [out (ByteArrayOutputStream.)]
(with-open [pdf-doc (Document. PageSize/A4 50 50 50 40)]
(doto pdf-doc
(PdfWriter/getInstance out)
.open
(.add (get-table))))
(.toByteArray out)))
;バイト列をHTTP Responseに書き込み
(defn write-response [bytes]
(let [in (ByteArrayInputStream. bytes)]
(-> (response/response in)
(response/header "Content-Disposition" "filename=test.pdf")
(response/header "Content-Length" (count bytes))
(response/content-type "application/pdf"))))
(defroutes app-routes
(GET "/" [] (write-response (get-pdf-data)))
(route/resources "/")
(route/not-found "Not Found"))
(def app
(handler/site app-routes))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment