这是我的第一个问题,我希望我做得对。对不起我的英语不好提前:))
我使用的是JSF 2.0(Eclipse IDE),我正在尝试使用Apache FOP 1.0生成一些PDF文件。
我能够使用Apache Fop site上的说明制作简单的PDF文件,但我无法从我的应用程序文件夹中插入任何图像。我的文件夹结构是这样的: 在我的应用程序WebContent我有(其他) pdf_transform / xslt / transformFile.xsl,和 pdf_transform / XSLT / logo.jpg
在transformFile.xsl中我有
<fo:block><fo:external-graphic src="url('logo.jpg')"/></fo:block>
但是当我在我的servlet中使用'showPDF'按钮时,我得到没有图像的PDF文件(其他一切都在那里),并在控制台中显示以下消息:
严重:返回的来源 来自URI解析不包含 用于URI的InputStream:logo.jpg 11月18日, 2010年5:16:49 PM org.apache.fop.events.LoggingEventListener processEvent SEVERE:找不到图像。 URI:logo.jpg。 (没有上下文信息 可用的)
我尝试使用'logo.jpg'而不是url('logo.jpg'),将图像放在WebContent文件夹中的各个位置并使用不同的导航(“./ logo.jpg”),但它没有用。< / p>
如果我设置绝对路径(例如“d:/fop/images/logo.jpg”),它可以正常工作,但我需要在我的应用程序中恢复。
在搜索时,我发现这与fopFactory.setURIResolver()和/或userAgent.setBaseURL()有关。尝试了一些,但没有成功。
我是JSF和FOP的新手,这种形象的情况一直困扰着我。有人可以帮我解决这个问题吗,或者至少指导一下“如何配置相对路径使用FOP”的教程?
编辑:我不想要任何绝对路径,应用程序应独立于计算机上的位置工作(可发布)。我的搜索告诉我它与配置FOP有关,但我不知道该怎么做:)
提前致谢。
P.S。这是一种被称为显示PDF的方法:
public void printExchangeRateList(ActionEvent event) {
BufferedOutputStream output = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
String path = externalContext.getRealPath("/");
try {
response.reset();
response.setHeader("Content-Type", "application/pdf");
output = new BufferedOutputStream(response.getOutputStream(), 10240);
File xsltfile = new File(path+"/pdf_transform/xslt/transformFile.xsl");
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltfile));
Source src = new DOMSource(makeXML()); // my method
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
} finally {
if (output != null) output.close();
/*try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
} catch (Exception e) {
// TODO Auto-generated catch block
}
facesContext.responseComplete();
}
答案 0 :(得分:11)
我找到了解决问题的方法。我以为我试过了,但那时我似乎犯了一些小错误。无论如何,使用以下代码
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String basePath = externalContext.getRealPath("/");
FopFactory fopFactory = FopFactory.newInstance();
fopFactory.setBaseURL(basePath);
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.setBaseURL(fopFactory.getBaseURL());
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output); // for some output
您可以使用从应用程序的WebContent文件夹开始的相对路径从xslt文件访问您的图像(和其他资源)。就我而言,我可以像这样访问logo.jpg
<fo:external-graphic src="url('pdf_transform/xslt/logo.jpg')"/>
让我有时间弄清楚这一点,我不明白为什么网上没有这样的基本事物的例子(或者我找不到它们)
注意:在FOP 2.0中,没有setBaseURL()
方法。而是将基本URL作为参数传递给FopFactory.newInstance()
。许多其他的制定者已被转移到FopFactoryBuilder。
答案 1 :(得分:2)
如果您可以访问图片的网址,则可以在生成报告时使用该网址,即http://localhost/images/logo.jpg。
但是,虽然我仍然在Web服务器上本地拥有图像,但我在XML文件中包含了应用程序的路径,并使用它如下:
<xsl:variable name="base_path" select="base-path"/>
<xsl:variable name="logo" select="companies/company/logo"/>
<fo:external-graphic src="url({$base_path}{logo})"/>
XML结构可能是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<base-path>/path/to/app/</base-path>
<companies>
<company>
<logo>images/company1.jpg</logo>
</company>
<company>
<logo>images/company2.jpg</logo>
</company>
</companies>
答案 2 :(得分:0)
我遇到了同样的问题并尝试了这个解决方案:
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
Request request = RequestCycle.get().getRequest();
//sort of a hack to find the path to the files that are in /img folder.
String baseUrl = request.getUrl().getProtocol()+"://"+request.getUrl().getHost()+":"+request.getUrl().getPort();
foUserAgent.setBaseURL(baseUrl);
然后,在XSL上我使用了:
<fo:external-graphic src="/img/image.png" />
要测试这是否有效,您应该能够在协议上看到图像:// link:port / img / image.png