在XSLT中具有URL时,使用fop和XSL生成PDF

时间:2019-04-04 20:12:56

标签: java spring pdf xslt apache-fop

在XSLT中具有URL时,使用fop和XSL生成PDF

我正在使用FOP 2.0和XSLT生成PDF。在这里,我从Web URL获取XSL。我的一个XSL URL是包括和导入其他XSL URL。如果它是单个XSL,则可以生成PDF。如果我在Web上的一个XSLT中具有多个URL。 FOP无法自动连接到其他URL [使用XSLTS的示例]


xsl:stylesheet xmlns:xsl =“ http://www.w3.org/1999/XSL/Transform” \

xmlns:fo =“ http://www.w3.org/1999/XSL/Format”版本=“ 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 SystemId未知;第4行;第34栏;样式表文件:footer.xsl发生IO异常 SystemId未知;第5行;第36栏;有样式表文件IO异常:mainbody.xsl SystemId未知;第6行;第41栏;样式表文件IO发生异常:secondarybody.xsl SystemId未知;第10行;第38栏; org.xml.sax.SAXException:ElemTemplateElement错误:布局 javax.xml.transform.TransformerException:ElemTemplateElement错误:布局 13:58:27.326 [http-nio-auto-1-exec-2]调试org.apache.fop.fo.FOTreeBuilder-构建格式化对象树 SystemId未知;第10行;第38栏;找不到名为:layout的模板

PDF生成器代码:

公共类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();
    }

1 个答案:

答案 0 :(得分:0)

只需替换

URL url = new URL(xslPath);
InputStream xslFile = url.openStream();
StreamSource xsltStreamSource = new StreamSource(xslFile);

作者

StreamSource xsltStreamSource = new StreamSource(xslPath);

并且XSLT处理器应该能够解析任何相对的导入或包含。

或者您将需要在xsltStreamSource上显式设置系统ID。但是我建议的一行应该可以完成这项工作。