Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the easiest way of converting an xhtml string to PDF using Flying Saucer?

I've been using Flying Saucer for a while now with awesome results.

I can set a document via uri like so

ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(xhtmlUri);

Which is nice, as it will resolve all relative css resources etc relative to the given URI. However, I'm now generating the xhtml, and want to render it directly to a PDF (without saving a file). The appropriate methods in ITextRenderer seem to be:

private Document loadDocument(final String uri) {
    return _sharedContext.getUac().getXMLResource(uri).getDocument();
}

public void setDocument(String uri) {
    setDocument(loadDocument(uri), uri);
}

public void setDocument(Document doc, String url) {
    setDocument(doc, url, new XhtmlNamespaceHandler());
}

As you can see, my existing code just gives the uri and ITextRenderer does the work of creating the Document for me.

What's the shortest way of creating the Document from my formatted xhtml String? I'd prefer to use the existing Flying Saucer libs without having to import another XML parsing jar (just for the sake of consistent bugs and functionality).

like image 943
Stephen Avatar asked Aug 06 '09 00:08

Stephen


2 Answers

The following works:

Document document = XMLResource.load(new ByteArrayInputStream(templateString.getBytes())).getDocument();

Previously, I had tried

final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);

final DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
Document document = documentBuilder.parse(new ByteArrayInputStream(templateString.getBytes()));

but that fails as it attempts to download the HTML docType from http://www.w3.org (which returns 503's for the java libs).

like image 76
Stephen Avatar answered Nov 07 '22 10:11

Stephen


I use the following without problem:

    final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setValidating(false);
    DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
    builder.setEntityResolver(FSEntityResolver.instance());
    org.w3c.dom.Document document = builder.parse(new ByteArrayInputStream(doc.toString().getBytes()));

    ITextRenderer renderer = new ITextRenderer();
    renderer.setDocument(document, null);
    renderer.layout();
    renderer.createPDF(os);

The key differences here are passing in a null URI, and also provided the DocumentBuilder with an entity resolver.

like image 1
Mark Derricutt Avatar answered Nov 07 '22 10:11

Mark Derricutt