LibreOfficeRenderer.java 2.73 KB
package com.brainfood.ofbiz;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;

import org.ofbiz.base.util.UtilIO;
import org.ofbiz.base.component.ComponentConfig;
import org.ofbiz.base.component.ComponentException;

import groovy.text.SimpleTemplateEngine;
import groovy.text.Template;
import groovy.lang.Writable;

public class LibreOfficeRenderer {
    public static void service(HttpServletRequest request, HttpServletResponse response, Map<String, Object> context) 
        throws InterruptedException, IOException, ClassNotFoundException, ComponentException {
        Object templateFile = context.get("_template");

        if (templateFile != null) {
            String fullPath = ComponentConfig.getRootLocation("driverup") + "/pdf-templates/" + templateFile.toString();

            String template = UtilIO.readString(new FileInputStream(fullPath));

            // FIXME: This is a hack. The Libreoffice file contains a $ declaration and this fixes it.
            context.put("Linux_X86_64", "$Linux_X86_64");
            context.put("Build", "$Build");

            StringBuilder output = new StringBuilder();
            int idx = 0;

            while (idx < template.length()) {
                int remaining = template.length() - idx;
                int chunkLength = remaining < 64000 ? remaining : 64000;
                String tmplChunk = template.substring(idx, idx + chunkLength);
                SimpleTemplateEngine engine = new SimpleTemplateEngine();
                Writable stTemplate = engine.createTemplate(tmplChunk).make(context);
                output.append(stTemplate.toString());
                idx += chunkLength;
            }

            File outputFile = File.createTempFile("bfdcs-", "-tmpl");
            UtilIO.writeString(outputFile, output.toString());

            ProcessBuilder pb = new ProcessBuilder("libreoffice", "--headless", "--convert-to", "pdf", outputFile.getPath(), "--outdir", outputFile.getParentFile().getPath());
            Map<String, String> env = pb.environment();
            env.put("HOME", "/home/ofbiz");
            env.put("USERNAME", "ofbiz");
            Process process = pb.start();
            InputStream is = process.getInputStream();
            process.waitFor();

            response.setContentType("application/pdf");
            UtilIO.copy(new FileInputStream(outputFile.getPath() + ".pdf"), true, response.getOutputStream(), true);

            outputFile.delete();
            new File(outputFile.getPath() + ".pdf").delete();
        }
    }
}