Clojure Office PDF Converter using LibreOffice headless

PDFs from Office Dokuments

I was looking for a way to convert docx and other document types to pdf on a backend written in clojure.

It turns out that there is a pretty well trodden path to convert to pdf files from Java backends: jodconverter. The work has already been done, thank you guys!!!

I am one of the untypical guys who writes clojure, clojurescript, fulcro software without having learned Java and javascript first. I learned clojure and clojurescript to scratch an itch and have to learn other languages to find out what people mean, when they reply in chats that this is "really a react problem".

So I realised that the documentation for jodconvert is pretty exaustive. When you understand Java that is…

So I got Java textbooks and leaned the OO way, which seems to me more to be a class-inheritance-way.

After 600 pages of textbooks and lots of exercise programms the jodconvert docs became less and less arcane and more and more readable. And when I understand enough Java I realise, that the documentation page that applies to me is this one.

Thank you Simon Braconnier, Mirko Nasato and all the other fine folks who invested the work!

The translation of the result to clojure is quite simple, once I understood the Java and the interop, thank you Rich Hickey!

LibreOffice

First LibreOffice has to be installed. In my case, on FreeBSD, that is:

sudo pkg install libreoffice

Test that LibreOffice –headless and Java work

Instructions are supplied by jobconverter here.

Doing it in clojure

I set up a clojure project with deps.edn and one file core.clj in the directory src.

deps.edn

{:paths ["src"]
 :deps {org.clojure/clojure  {:mvn/version "1.10.1"}
        org.jodconverter/jodconverter-local {:mvn/version "4.3.0"}} }

src/core.clj

(ns core
  (:require
   [clojure.java.io :refer [file]])
  (:import
   org.jodconverter.local.office.LocalOfficeManager
   org.jodconverter.core.office.OfficeUtils
   org.jodconverter.local.JodConverter))

(def office-manager (LocalOfficeManager/install))

(defn start-office-manager [office-manager]
  (.start office-manager))

(defn convert [in-file-string out-file-string]
  (-> in-file-string
      file
      JodConverter/convert
      (.to (file out-file-string))
      .execute))

(defn stop-office-manager [office-manager]
  (OfficeUtils/stopQuietly office-manager))

That's it. Integration into my own software is easy clojure from here.

So spending about 30 hours to learn some Java paid off.