使用apache fop和PipedOutputStream

时间:2014-02-26 13:30:37

标签: java jaxb inputstream outputstream apache-fop

我想使用apache fop生成一个来自jaxb-object的pdf文件来生成和迭代PdfStamper来修改它。因为fop写入outputStream并且PdfStamper从InputStream读取,我的想法是使用Piped [I | O] Streams。这是我试过的:

public void transform2XSLFO_onthefly(Medium medium, OutputStream out) throws Exception {
       PipedInputStream pInputPipe = new PipedInputStream();
       PipedOutputStream outputTemp = new PipedOutputStream(pInputPipe);

try {

        JAXBSource source = new JAXBSource( JAXBContext.newInstance(medium.getClass()) , medium );

          FOUserAgent userAgent = fopFactory.newFOUserAgent();
           // settings
        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent ,outputTemp);


        InputStream XSLinputStream = xslfoStylesheet.getInputStream();
        StreamSource XSLsource = new StreamSource(XSLinputStream);

        Result res = new SAXResult(fop.getDefaultHandler());

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer(XSLsource);



        // run transformation
        t.transform(source, res);
        // does not come so far, no use closing the stream
        outputTemp.close();

        PdfReader reader = new PdfReader(pInputPipe);
        pdfStamper = new PdfStamper(reader, out);
        //..... postProcess...
        pdfStamper.close();

    } catch (Exception ex) {
        log.error("ERROR", ex);
    }

然而,它挂在“t.transform(source,res);”行中,看起来他正在等待fop-transformation中间的某些东西。它使用BypeArrayOutputStream并将其转换为输入流并将其用于PdfStamper输入:

 InputStream pdfInput = new ByteArrayInputStream(((ByteArrayOutputStream) outputTemp).toByteArray());   

但文件可以变得非常大(几MB),所以我认为管道版本会更好!你觉得怎么样?

1 个答案:

答案 0 :(得分:0)

您应该阅读有关如何使用PipeInput / OutputStream的信息。 FOP和PdfStamper需要在不同的线程中运行。基本上,这与FOP本身无关。我相信你会在网上找到各种有关其工作原理的例子。如果您对多线程编程不满意,我建议您只在byte []或临时文件中缓冲FOP的输出。