我尝试做一个简单的servlet,它基于HTML模板生成pdf文件。我尝试使用Thymeleaf和FlyingSaucer,如example
在我的template.hmtl文件中,我的样式如下:
<link rel="stylesheet" type="text/css" media="all" href="style.css"/>
它永远不会被加载。没错,没事,只是导致.pdf缺少样式。如果我将样式文件的内容放到template.HTML中,它的工作方式就像是魅力。
如果我放这样的东西:
<link rel="stylesheet" type="text/css" media="all" href="http://localhost:8080/MY_APP/resources/style.css"/>
有效。
我所有的资源都在src/main/webapp/resources
下。
答案 0 :(得分:0)
经过几个小时的研究问题,这就是我最终得到的结果。
对于CSS-我发现的唯一解决方案是将CSS放入HTML模板中。不是很优雅,但是可以完成这项工作(至少目前如此)。没什么大问题,因为我使用这些模板生成pdf文件。
但是图像文件也存在同样的问题,但是我能够用一种优雅的方式解决这个问题。就是这里!
问题在于Java在Web容器中找不到指向.html模板的指向的文件。 因此,我不得不编写自定义Element Factory来扩展ReplacedElementFactory。这是该代码:
public class B64ImgReplacedElementFactory implements ReplacedElementFactory {
public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) {
Element e = box.getElement();
if (e == null) {
return null;
}
String nodeName = e.getNodeName();
if (nodeName.equals("img")) {
String attribute = e.getAttribute("src");
FSImage fsImage;
try {
fsImage = buildImage(attribute);
} catch (BadElementException e1) {
fsImage = null;
} catch (IOException e1) {
fsImage = null;
}
if (fsImage != null) {
if (cssWidth != -1 || cssHeight != -1) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
}
return null;
}
protected FSImage buildImage(String srcAttr) throws IOException, BadElementException {
URL res = getClass().getClassLoader().getResource(srcAttr);
if (res != null) {
return new ITextFSImage(Image.getInstance(res));
} else {
return null;
}
}
public void remove(Element e) {
}
public void reset() {
}
@Override
public void setFormSubmissionListener(FormSubmissionListener listener) {
}
}
和生成PDF文件的代码中的用例:
ITextRenderer renderer = new ITextRenderer();
SharedContext sharedContext = renderer.getSharedContext();
sharedContext.setReplacedElementFactory(new B64ImgReplacedElementFactory());
custom元素replace捕获所有'img'节点,并使用ClasLoader获取资源路径,并基于此返回FSImage,这就是我们所需要的。
希望有帮助!