What's the easiest way of converting an xhtml

2020-07-10 08:28发布

问题:

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).

回答1:

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).



回答2:

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.