PDF Publication

A PDF Publication can be done in several ways:

  • Option 1 : Making a HTML publication (with a standard Simplicité Publication Template or a Mustache Custom Template). It will open a new tab the user can then “print as” pdf from its own brower. This is the cheapest option.
    • Upsides : beautiful, easy-to-develop, easy-to-maintain publications
    • Downsides : impossibility to generate the PDF on the server (to send by email, or save on the object for example)
  • Option 2 : using a HTML publication + a third-party service to turn the generated HTML/CSS/JS into a PDF document.
    • option A: rolling an on premise service with tools like https://wkhtmltopdf.org/ [free] or https://jsreport.net
    • option B: using an online service (there are plenty) (generally not free)
    • Upsides: same as option 1 + reliability & server-side rendering
    • Downsides: external service, either not free or with maintenance
  • Option 3 : using a HTML publication & buy and add the iText library to your project to turn the generated HTML/CSS/JS into a PDF document. (we have not tested this option)
    • Upsides: same as option 1 + reliability & server-side rendering + full Java (no external process to install)
    • Downsides: library price + install complexity to add lib
  • Option 4 : use a PDF publication using open source Apache PDFBox
    • Upsides: reliability & server-side rendering + full Java (no external process to install)
    • Downsides: dev complexity (PDFs are hard to generate this way)

TL;DR :

HTML Publication (1) HTML Pub + HTML to PDF service (2A) JSON to PDF service (2B) Java iText HTML to PDF (3) Java Apache PDFBox (4)
Code complexity / Maintainability easy easy none easy hard
Install / Operations complexity none easy (service) / medium (docker) / hard (non docker) easy (cloud) / hard (on premise) medium (include external lib) none (lib included)
PDF rendering (server=> consistent+PDF savable and sendable by mail) client side (HTML page > save as > PDF) server (Simplicité calls webservice) server (Simplicité calls webservice) server server
Template editable by client Edit HTML in Simplicité Edit HTML in Simplicité Editable & user-friendly No No
Open Source / Free yes yes no no yes

Disclaimer: Simplicité contains an old iText “open source” 2.1.7 version, which is currently used by Simplicité’s PDFTool. We are planning to move away from iText 2.1.7 for licensing matters, so even though it is shiped with Simplicité we do NOT encourage you to use it in your custom code.

Options 2A and 4 are documented below.

2 Likes

Example Publication with Apache PDFBox


Object Configuration

MyObject
- Publication
  - MyPublication
    - Usage: ...
    - Grantable: no
    - MIME Type: PDF
    - Type: Method
    - Method: pubPdf

Code Example

package com.simplicite.objects.Demo;

import com.simplicite.util.*;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.font.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Customer business object
 */
public class DemoClient extends ObjectDB {
	private static final long serialVersionUID = 1L;
	
	//inspiration : https://www.tutorialspoint.com/pdfbox/
	public byte[] pubPdf(){
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		
		try{
			// init
			PDDocument document = new PDDocument();
			PDPage page = new PDPage();
			document.addPage(page);
			
			// content
			PDPageContentStream contentStream = new PDPageContentStream(document, page);
			contentStream.beginText();
			contentStream.setFont(PDType1Font.TIMES_ROMAN, 12);
			contentStream.newLineAtOffset(25, 500);
			contentStream.showText("Hello world");
			contentStream.endText();
			contentStream.close();
			
			// save
			document.save(byteArrayOutputStream);
			document.close();
		}
		catch(IOException e){
			AppLog.error(getClass(), "pubPdf", "Error creating PDF", e, getGrant());
		}
		
		return byteArrayOutputStream.toByteArray();
	}
}
1 Like

Sample publication using wkhtml2pdf

In this example, we use Docker Compose to install Simplicité + Postgres + wkhtml2pdf

Installing

sudo yum update -y && sudo yum clean all
sudo reboot
sudo yum install -y docker && sudo yum clean all
sudo systemctl enable docker
sudo systemctl start docker
sudo docker login
# copy content in docker-compose.yml shown below
vi docker-compose.yml
sudo docker-compose up -d

docker-compose.yml

version: "3"
services:
  db:
    image: postgres:latest
    restart: always
    container_name: myinstance-postgres-database
    environment:
      POSTGRES_USER: "simplicite"
      POSTGRES_PASSWORD: "simplicite"
      POSTGRES_DB: "simplicite"
    ports:
    - 127.0.0.1:5432:5432
    volumes:
    - myinstance-postgres-db:/var/lib/postgresql/data
  wkhtml2pdf:
    image: openlabs/docker-wkhtmltopdf-aas:latest
    restart: always
  web:
    image: simplicite/platform:latest
    restart: always
    container_name: myinstance-postgres-webapp
    environment:
      DB_SETUP: "true"
      DB_VENDOR: "postgresql"
      DB_HOST: db
      DB_USER: "simplicite"
      DB_PASSWORD: "simplicite"
      DB_NAME: "simplicite"
      DB_WAIT: 10
    ports:
     - 80:8080
    volumes:
    - myinstance-postgres-git:/usr/local/tomcat/webapps/ROOT/WEB-INF/git
    depends_on:
    - db
volumes:
  myinstance-postgres-db:
  myinstance-postgres-git:

Configuration

MyObject
- Publication
  - MyPublication
    - Usage: ...
    - Grantable: no
    - MIME Type: PDF
    - Type: Method
    - Method: pubPdf

Code example

For more information on generating the HTML, see HTML publication using resources

package com.simplicite.objects.Demo;

import java.util.*;
import com.simplicite.util.*;
import com.simplicite.util.tools.*;
import org.json.JSONObject;

/**
 * Business object DemoSupplier
 */
public class DemoSupplier extends ObjectDB {
	private static final long serialVersionUID = 1L;
	
	public byte[] pubPdf(){
		String url = "http://wkhtml2pdf/";
		String user = null;
		String password = null;
		JSONObject postData = new JSONObject();
		postData.put("contents", Tool.toBase64("<html><head><meta charset=\"utf-8\"></head><h1>Simplicité / Docker Compose / wkhtml2pdf</h1><p>...by Simplicité</p></html>"));
		String[] headers = {"Content-Type:application/json"};
		String encoding = Globals.BINARY;
		byte[] pdf = null;
		
		try{
			pdf = Tool.readUrlAsByteArray(url, user, password, postData.toString(), headers, encoding);
		}catch(Exception e){
			AppLog.error(getClass(), "pubPdf", "------------", e, getGrant());
		}
		return pdf;
	}
}