Solution facile:
Si vous voulez un test rapide pour voir si votre document travaillera avec vos styles (sans écrire beaucoup de code pour l'intégrer dans votre application). Il suffit de copier et coller le CSS dont vous avez besoin dans votre page.
Plus travail Solution
Ma solution a été de lire le CSS et le mettre en html avec un préprocesseur. Comme il s'agissait d'une application plus ancienne qui n'était peut-être pas entièrement compatible xhtml, j'ai utilisé JSoup pour charger le code HTML. Le code ci-dessous fait le pré-traitement. Je dirai que ce sont des extraits de code pour vous aider à démarrer. La bonne chose, une fois que vous l'avez fait fonctionner, c'est que vous pouvez transformer n'importe quelle page sur votre serveur en PDF sans code supplémentaire. Dans ma situation, je configure un filtre pour rechercher un paramètre spécifique. Si ce paramètre est présent, j'enveloppe la requête avec un wrapper de demande pour accéder aux octets restitués finaux de la page html. J'utilise ensuite Jsoup pour l'analyser, puis pre = le traiter.
/**this method uses JSOUP Document here is org.jsoup.nodes.Document
*/
@Override
public void modifyDOM(MyResourceResolver resources, Document normalizedDOM) {
//move style into head section
Elements styleTags = normalizedDOM.getElementsByTag("style");
normalizedDOM.select("style").remove();
for (org.jsoup.nodes.Element linkElement : styleTags) {
String curHead = normalizedDOM.head().html();
normalizedDOM.head().html(curHead + "\n" + linkElement.html() + "\n");
}
//now resolve css
Elements links = normalizedDOM.getElementsByTag("link");
for (org.jsoup.nodes.Element linkElement : links) {
String linkHref = linkElement.attr("href");
if (linkHref == null) {
linkHref = "";
}
String mediaSelector = linkElement.attr("media");
if (mediaSelector == null) {
mediaSelector = "";
}
mediaSelector = mediaSelector.trim();
if ("".equalsIgnoreCase(mediaSelector) || ("print".equalsIgnoreCase(mediaSelector))) {
byte[] contents = resources.getContentsOfHref(linkHref);
if (null != contents) {
//we've got the info let's add to the document as is
Tag styleTag = Tag.valueOf("style");
Attributes styleAttributes = new Attributes();
styleAttributes.put("type", "text/css");
String baseUri = "";
org.jsoup.nodes.Element styleElement = new Element(styleTag, baseUri, styleAttributes);
styleElement.text(new String(contents));
String curHead = normalizedDOM.head().html();
normalizedDOM.head().html(curHead + "\n<style type='text/css'>" + styleElement.html() + "</style>\n");
}
}
}
normalizedDOM.select("link").remove();
normalizedDOM.select("script").remove();
}
Depuis que je suis l'insertion de la soucoupe volante css et ne supporte pas javascript, je supprimer simplement les références du document à la fin du pré traitement. la classe MyResourceResolver est juste une classe I qui a écrit une référence au contexte de servlet. la méthode qui lit réellement les octets du hors css du serveur ressemble à ceci:
public byte[] getContentsOfHref(String href) {
byte[] retval = null;
byte[] buf = new byte[8195];
int nread;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream is = null;
try {
if (href.startsWith("/myurlcontext")) {
href = href.substring("/myurlcontext".length());
}
is = context.getResourceAsStream(href);
while ((nread = is.read(buf)) >= 0) {
bos.write(buf, 0, nread);
}
retval = bos.toByteArray();
} catch (Exception ex) {
//do nothing for now
} finally {
try {
is.close();
} catch (Exception ex) {/*do nothing*/}
}
if (retval == null) {
System.out.println("Did not find: " + href);
} else {
System.out.println("Found: " + href + " " + retval.length + " bytes");
}
return retval;
}
La question suivante, comment initialiser JSOUP Dom.Eh bien, je le fais dans un emballage de demande qui lit le contenu de la page JSP rendu et passe à mon code de production PDF:
String renderedJSPString = new String(renderedJSP);
//these escape sequences are nuisance in xhtml.
renderedJSPString = renderedJSPString.replaceAll(" |©|&|<|>", "");
org.jsoup.nodes.Document parsedHtmlDOM = Jsoup.parse(renderedJSPString);
org.jsoup.nodes.Document normalizedDOM = parsedHtmlDOM.normalise();
normalizedDOM.outputSettings().escapeMode(Entities.EscapeMode.xhtml);
normalizedDOM.outputSettings().prettyPrint(true);
...
preProcessor.modifyDOM(resolver, normalizedDOM);
...
En l'ajoutant _also_ aux cacerts java default, il a été corrigé. (--server.ssl.key-store est seulement pour tomcat) – lilalinux