1 year ago

#155417

test-img

kenrick tam

Is there anyway to convert ITextRenderer to base64 encoded string?

Recently I want to create a util to convert the html into pdf (base64 encoded string) and then store the string into database. Therefore I had choose flying-saucer to do the work. Below is the util for doing the job.

import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xml.sax.SAXException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;

import java.util.List;
import java.util.Map;


private static Document generateDoc(TemplateEngine templateEngine, String templateName, Map<String, Object> variables) throws IOException, ParserConfigurationException, SAXException {
        // Generate the Document
        final Context context = new Context();
        context.setVariables(variables);
        StringWriter stringWriter = new StringWriter();
        try(BufferedWriter writer = new BufferedWriter(stringWriter)) {
            templateEngine.process(templateName,context, writer);
            writer.flush();
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            return builder.parse(new ByteArrayInputStream(stringWriter.toString().getBytes()));
        }catch (Exception e){
            throw e;
        }
    }

private static void generateAll(TemplateEngine templateEngine, String templateName, OutputStream out, List<Map<String, Object>> listVars) throws Exception {
        ITextRenderer renderer = new ITextRenderer();
        //set the font family
        ITextFontResolver fontResolver = renderer.getFontResolver();
        //Convert Code128 class to barcode image
        renderer.getSharedContext().setReplacedElementFactory(new BarcodeReplacedElementFactory(renderer.getOutputDevice()));
        //default the font family
        fontResolver.addFont("static/fonts/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

        //Use for loop to append the result into same pdf
        //0 means create pdf
        for (int i = 0; i < listVars.size(); i++) {
            Document docAppend = generateDoc(templateEngine, templateName, listVars.get(i));
            renderer.setDocument(docAppend, null);
            //Export the pdf
            renderer.layout();
            if(i==0){
                renderer.createPDF(out, false);
            }else {
                //Write next page of pdf
                renderer.writeNextDocument();
            }

        }
        PdfWriter pdfWriter = renderer.getWriter();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        String base64 = Base64.encodeBase64String(baos.toByteArray());

        System.out.println(base64);

        renderer.finishPDF(); //Finish pdf written
    }

//Use to preview the pdf (debug use)
public static void preview(TemplateEngine templateEngine, String templateName, List<Map<String, Object>> listVars, HttpServletResponse response) {
        try (ServletOutputStream out = response.getOutputStream()) {
            generateAll(templateEngine, templateName, out, listVars);
            out.flush();
            System.out.println("Raw: "+out);
            System.out.println("Base64:");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

Is there any way to convert the pdf into the base64 code? Throughout the research I had found that PDFReader may help me, when I tried to use PDFReader to convert to ServletOutputstream into ByteArrayOutputStream, it throws error.

Edited

Code Attempt to convert the information into base64

(P.S. I put this function just before the renderer.finshPDF())

PdfReader reader = new PdfReader(((ByteArrayOutputStream)out).toByteArray());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, baos);
stamper.close();
String base64 = Base64.encodeBase64String(baos.toByteArray());
System.out.println(base64);

Error

class org.apache.catalina.connector.CoyoteOutputStream cannot be cast to class java.io.ByteArrayOutputStream (org.apache.catalina.connector.CoyoteOutputStream is in unnamed module of loader 'app'; java.io.ByteArrayOutputStream is in module java.base of loader 'bootstrap')

java

itext

thymeleaf

flying-saucer

0 Answers

Your Answer

Accepted video resources