当前位置: 首页 > 知识库问答 >
问题:

一个FOP XSLT转换,但呈现不同的文件

萧宣
2023-03-14

有没有办法只进行一次xslt转换并将输出呈现为pdf、png、svg文件?

StreamSource contentSource = new StreamSource(xmlContentStream);
StreamSource transformSource = new StreamSource(xslFoMarkupStream);

ByteArrayOutputStream outStream = new ByteArrayOutputStream();

Transformer xslfoTransformer = getTransformer(transformSource);

Fop fop = fopFactory.newFop("application/pdf", foUserAgent, outStream);

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

// Start XSLT transformation and FOP processing
xslfoTransformer.transform(contentSource, res);

xmlContentStream.close();
xslMarkupStream.close();
return outStream;

在上面的例子中,为了生成PDF然后生成PNG,我必须创建一个具有不同mime类型的新Fop实例,然后再次调用xslfoTransformer.transform()。

这意味着我将有两次转换,但我想知道是否有一种方法可以运行一次转换,然后将输出渲染为不同的格式?(自定义渲染器?)

或者有什么建议可以加快渲染速度,因为我还需要做几次——一次是PDF,PNG,SVG。

我还尝试通过FOP生成PDF,然后通过Apache PdfBox将其转换为图像。这样工作起来稍微快一点,但是看起来很傻。

谢谢你。

共有1个答案

夔宏深
2023-03-14

您可以节省一步。您的代码执行上述两个步骤:获取一些任意XML,使用XSLT将其转换为XSL: FO,然后将输出呈现为您想要的任何格式。您可以将XML转换为XSL: FO(可能是较慢的部分)一次,并将该结果用作2个FO实例的输入。类似这样的东西:

    public void fopReport(OutputStream pdfOut, OutputStream jpgOut, Source xmlSource, Source xsltSource) throws Exception {
            // Create the FO content
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(xsltSource);
            ByteArrayOutputStream foBytesStream = new ByteArrayOutputStream();
            StreamResult foByteStreamResult = new StreamResult(foBytesStream);
            transformer.transform(xmlSource, foByteStreamResult);
            byte[] foBytes = foBytesStream.toByteArray();

            // Render twice
            FopFactory fopFactory = FopFactory.newInstance();
            FOUserAgent uaPDF = fopFactory.newFOUserAgent();
            FOUserAgent uaJpg = fopFactory.newFOUserAgent();

            Fop fopPDF = fopFactory.newFop(MimeConstants.MIME_PDF, uaPDF, pdfOut);
            Fop fopJpg = fopFactory.newFop(MimeConstants.MIME_JPEG, uaJpg, jpgOut);

            //PDF
            Source src = new StreamSource(new ByteArrayInputStream(foBytes));
            Transformer resultTransformer = factory.newTransformer();
            resultTransformer.transform(src, new SAXResult(fopPDF.getDefaultHandler()));

            //JPF
            src = new StreamSource(new ByteArrayInputStream(foBytes));
            resultTransformer = factory.newTransformer();
            resultTransformer.transform(src, new SAXResult(fopJpg.getDefaultHandler()));
        }

希望有帮助

 类似资料:
  • 我使用的是来自的fonthttp://fonts.googleapis.com/css?family=Open Sans。由于安全原因,一些客户端使用封闭环境,因此我需要使用从npm安装的本地字体。 我尝试了npm为提供的多个软件包,如,,但使用相同css的字体与以前使用GoogleApis字体呈现的字体不同,尤其是

  • 问题内容: 我正在尝试仅将原始文件从一个目录复制到另一个目录,但是某些文件具有相同的名称…我正在尝试使用哈希来比较文件,如果其不在目录中发送并且名称相同,它到file_name.something。目前,我正在获取一些文件,并且具有相同名称的文件正在被覆盖…任何人都可以提出建议吗? 问题答案: 您将哈希与文件名进行比较。你需要类似的东西 计算目标文件夹中每个文件的哈希值。 此外,在当前版本中,您的

  • 问题内容: 因此,我有一个带有按钮的根视图控制器,当用户按下该按钮时,将显示另一个视图控制器。第二个控制器具有一个关闭选项,该选项仅返回到根视图控制器,还有一个按钮,当用户触摸它时,该按钮将关闭当前视图控制器,以便它再次返回到根视图控制器并显示另一个按钮。转到我使用的第一个控制器: 在另一个视图控制器中,我选择仅关闭的按钮,然后执行此操作。 因此,对于需要解雇并显示另一个控制器的第二个控制器,我尝

  • 我正在构建一个文本语音应用程序。我正在使用splitpane来显示它。左窗格显示动态变化的语音到文本信息。右窗格显示一个“是/否”固定文本为每个句子说在左窗格在同一级别。 为了确保“Yes/No”显示在与左窗格中的句子完全相同的级别上,每当说出新句子时,我将在左窗格和右窗格中添加文本到相应的HBox(Splitpane_left_hbox(语音到文本句子)和Splitpane_right_hbox

  • 问题内容: 在FF或Chrome中渲染时,红色div的高度为26px,而黄色div的高度为20px。如何使红色的div呈现与黄色的div相同,但不包含任何文本呢? 问题答案: 只是一个想法: 只要div中没有​​文本,就将其视为行内图像(或其他内容),因此将vertical-align设置为“基准”(或文本底部或其他内容)而不是“底部”。 解决方案: 要更正此问题,请在您的内部div上进行设置。绝