在 XSLT 中包含 URL 时使用 fop 和 XSL 生成 PDF
Generating PDF using fop and XSL when having URLS in XSLT
在 XSLT 中具有 URLS 时使用 fop 和 XSL 生成 PDF
我正在使用 FOP 2.0 和 XSLT 生成 PDF。我在这里从网络 url 获取 XSL。我的一个 XSL URL 包含并导入其他 url 的 XSL。如果它是单个 XSL,我可以生成 PDF。如果我在 Web 上的一个 XSLT 中有多个 URLS。 FOP 无法自动连接到其他 URLS[ 使用 XSLTS 的示例]
xsl:样式表xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\
xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<xsl:include href="abc.xsl"/>
<xsl:include href="xyz.xsl"/>
<xsl:include href="wgh.xsl"/>
这就是它在一个 XSL 中包含 XSL 的方式。在这种情况下,我的 FOP 没有重定向到那些 xsls 并且无法生成 PDF
错误:
SystemId 未知;第 3 行;第 34 列;样式表文件出现 IO 异常:header.xsl
系统 ID 未知;第 4 行;第 34 列;样式表文件出现 IO 异常:footer.xsl
系统 ID 未知;第 5 行;第 36 列;样式表文件出现 IO 异常:mainbody.xsl
系统 ID 未知;第 6 行;第 41 列;样式表文件出现 IO 异常:secondarybody.xsl
系统 ID 未知;第 10 行;第 38 列; org.xml.sax.SAXException:ElemTemplateElement 错误:布局
javax.xml.transform.TransformerException:ElemTemplateElement 错误:布局
13:58:27.326 [http-nio-auto-1-exec-2] DEBUG org.apache.fop.fo.FOTreeBuilder - 构建格式化对象树
系统 ID 未知;第 10 行;第 38 列;找不到名为:layout
的模板
PDF 生成器代码:
public class PdfGenerator {
private static final Logger LOG=LoggerFactory.getLogger(PdfGenerator.class);
public List<OutputStream> generatePdfs(List<Content> xmlList, int reqestListSize,String xslPath)
{
试试{
List<OutputStream> pdfOutputStreams= new ArrayList();
for(int p = 0; p <reqestListSize; p++) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String jaxbType = "com.abc.model"; // model package
JAXBContext context = JAXBContext.newInstance(jaxbType);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE);
marshaller.marshal(xmlList.get(p),bos);
ByteArrayInputStream inStream = new ByteArrayInputStream(bos.toByteArray());
StreamSource xmlSource = new StreamSource(inStream);
// create an instance of fop factory
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
// a user agent is needed for transformation
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
ByteArrayOutputStream tempOutputStream = new ByteArrayOutputStream();
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, tempOutputStream);
pdfOutputStreams.add(p, tempOutputStream);
// Setup XSLT
TransformerFactory transformerFactory = TransformerFactory.newInstance();
URL url = new URL(xslPath);
InputStream xslFile = url.openStream(); ( **http://home.www.test.com/abc_web/xsl/test.xsl** ( Using an url to get XSLT. faild loading due to XSL :include) )
StreamSource xsltStreamSource = new StreamSource(xslFile);
Transformer transformer = transformerFactory.newTransformer(xsltStreamSource);
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
// That's where the XML is first transformed to XSL-FO and then
// PDF is created
transformer.transform(xmlSource, res);
}
return pdfOutputStreams;
}catch(Exception ex) {
LOG.error("Error", ex);
return new ArrayList();
}
简单替换
URL url = new URL(xslPath);
InputStream xslFile = url.openStream();
StreamSource xsltStreamSource = new StreamSource(xslFile);
和
StreamSource xsltStreamSource = new StreamSource(xslPath);
并且 XSLT 处理器应该能够解析任何相关的导入或包含。
或者您需要在 xsltStreamSource
上明确设置 SystemId
。但是我建议的单行应该可以很好地完成工作。
在 XSLT 中具有 URLS 时使用 fop 和 XSL 生成 PDF
我正在使用 FOP 2.0 和 XSLT 生成 PDF。我在这里从网络 url 获取 XSL。我的一个 XSL URL 包含并导入其他 url 的 XSL。如果它是单个 XSL,我可以生成 PDF。如果我在 Web 上的一个 XSLT 中有多个 URLS。 FOP 无法自动连接到其他 URLS[ 使用 XSLTS 的示例]
xsl:样式表xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\
xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<xsl:include href="abc.xsl"/>
<xsl:include href="xyz.xsl"/>
<xsl:include href="wgh.xsl"/>
这就是它在一个 XSL 中包含 XSL 的方式。在这种情况下,我的 FOP 没有重定向到那些 xsls 并且无法生成 PDF
错误:
SystemId 未知;第 3 行;第 34 列;样式表文件出现 IO 异常:header.xsl 系统 ID 未知;第 4 行;第 34 列;样式表文件出现 IO 异常:footer.xsl 系统 ID 未知;第 5 行;第 36 列;样式表文件出现 IO 异常:mainbody.xsl 系统 ID 未知;第 6 行;第 41 列;样式表文件出现 IO 异常:secondarybody.xsl 系统 ID 未知;第 10 行;第 38 列; org.xml.sax.SAXException:ElemTemplateElement 错误:布局 javax.xml.transform.TransformerException:ElemTemplateElement 错误:布局 13:58:27.326 [http-nio-auto-1-exec-2] DEBUG org.apache.fop.fo.FOTreeBuilder - 构建格式化对象树 系统 ID 未知;第 10 行;第 38 列;找不到名为:layout
的模板PDF 生成器代码:
public class PdfGenerator {
private static final Logger LOG=LoggerFactory.getLogger(PdfGenerator.class);
public List<OutputStream> generatePdfs(List<Content> xmlList, int reqestListSize,String xslPath)
{ 试试{
List<OutputStream> pdfOutputStreams= new ArrayList();
for(int p = 0; p <reqestListSize; p++) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String jaxbType = "com.abc.model"; // model package
JAXBContext context = JAXBContext.newInstance(jaxbType);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE);
marshaller.marshal(xmlList.get(p),bos);
ByteArrayInputStream inStream = new ByteArrayInputStream(bos.toByteArray());
StreamSource xmlSource = new StreamSource(inStream);
// create an instance of fop factory
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
// a user agent is needed for transformation
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
ByteArrayOutputStream tempOutputStream = new ByteArrayOutputStream();
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, tempOutputStream);
pdfOutputStreams.add(p, tempOutputStream);
// Setup XSLT
TransformerFactory transformerFactory = TransformerFactory.newInstance();
URL url = new URL(xslPath);
InputStream xslFile = url.openStream(); ( **http://home.www.test.com/abc_web/xsl/test.xsl** ( Using an url to get XSLT. faild loading due to XSL :include) )
StreamSource xsltStreamSource = new StreamSource(xslFile);
Transformer transformer = transformerFactory.newTransformer(xsltStreamSource);
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
// That's where the XML is first transformed to XSL-FO and then
// PDF is created
transformer.transform(xmlSource, res);
}
return pdfOutputStreams;
}catch(Exception ex) {
LOG.error("Error", ex);
return new ArrayList();
}
简单替换
URL url = new URL(xslPath);
InputStream xslFile = url.openStream();
StreamSource xsltStreamSource = new StreamSource(xslFile);
和
StreamSource xsltStreamSource = new StreamSource(xslPath);
并且 XSLT 处理器应该能够解析任何相关的导入或包含。
或者您需要在 xsltStreamSource
上明确设置 SystemId
。但是我建议的单行应该可以很好地完成工作。