嵌入式HTML的PDF报告

PM *_*7-1 10 html java xslt xsl-fo apache-fop

我们有一个基于Java的系统,该系统从数据库中读取数据,合并与预设的各数据字段XSL-FO标签和结果转换为PDFApache FOP.

XSL-FO格式中它看起来像这样:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Html [
<!ENTITY nbsp  "&#160;"> 
    <!-- all other entities -->
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/">

        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" font-family="..." font-size="...">
            <fo:layout-master-set>          
                <fo:simple-page-master master-name="Letter Page" page-width="8.500in" page-height="11.000in">

                    <!-- appropriate settings -->

                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="Letter Page">

                <!-- some static content -->

            <fo:flow flow-name="xsl-region-body">
                    <fo:block>
                        <fo:table ...>
                            <fo:table-column ... />
                            <fo:table-body>
                                <fo:table-row>
                                    <fo:table-cell ...>
                                        <fo:block text-align="...">
                                            <fo:inline font-size="..." font-weight="...">
                                                <!-- Header / Title -->
                                            </fo:inline>
                                        </fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </fo:table-body>
                        </fo:table>
                    </fo:block>

                    <fo:block>

                        <fo:table ...>
                            <fo:table-column ... />
                            <fo:table-body> 
                                <fo:table-row>
                                    <fo:table-cell>
                                        <fo:block ...>
                                            <!-- Field A -->                                
                                        </fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </fo:table-body>
                        </fo:table>

                        <!-- Other fields in a very similar fashion as the above "Field A" -->

                    </fo:block>

                </fo:flow>      

            </fo:page-sequence>

        </fo:root>              

    </xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

现在我正在寻找一种方法来允许一些字段包含静态HTML格式的内容.此内容将通过我们的支持HTML编辑器生成(沿着线的东西CLEditor,CKEditor等),或者从外部粘贴.

我的计划是遵循这篇JavaWorld文章的配方:

  • 用于JTidy将HTML格式的字符串转换为正确的XHTML
  • 进一步修改Antenna House中的xhtml2fo.xsl以删除所有文档范围和页面范围的转换
  • 将此修改后的XSLT应用于我的XHTML字符串(javax.xml.transform)
  • 使用XPath(javax.xml.xpath)提取根目录下的所有节点
  • 将结果直接提供给现有的XSL-FO文档

我有这样的代码的裸骨版本,并得到以下错误:

(错误的位置未知)org.apache.fop1.fo.ValidationException:"{ http://www.w3.org/1999/XSL/Format } table-body"不是"fo:block"的有效子项!(没有上下文信息)

我的问题:

  1. 解决此问题的方法是什么?
  2. 可以<fo:block>作为通用容器与其他对象(包括表)嵌套在里面吗?
  3. 这是解决任务的整体合理方法吗?

如果某人已" 在那里做过 ",请分享您的经验.

Kev*_*own 3

排除故障的最佳方法是使用验证查看器/编辑器来检查 XSL FO。许多(例如 oXygen)会在您打开它们时向您显示 XSL FO 结构中的错误,并且它们将描述问题(就像报告的错误一样)。

在您的情况下,您显然有一个 fo:table-body 作为 fo:block 的子项。它不可能是。fo:table-body 只有一个有效的父对象 fo:table。您可能缺少 fo:table 标记,或者在此位置错误地插入了 fo:block。

在我看来,我做的事情可能会略有不同。我会将 XHTML 内容内联到 XSL FO 中您想要的位置。然后,我将创建一个身份转换,复制所有基于 fo 的内容,但使用 XSL 转换 XHTML 部分。这样,您实际上可以在像 oXygen 这样的 XSL 编辑器中进行转换,并查看错误发生的位置以及确切的原因。就像任何其他调试器一样。

注意:您可能还希望查看其他 XSL,特别是如果您的 HTML 可能具有任何 style="" CSS 属性。如果是这种情况,那么它不是简单的 HTML,那么您将需要一种更好的方法来将 CSS 的 HTML 处理为 FO。

http://www.cloudformatter.com/css2pdf就是基于这个完整的转换。该通用样式表可在此处找到:http://xep.cloudformatter.com/doc/XSL/xeponline-fo-translate-2.xsl

我是该样式表的作者。它的作用比您要求的要多得多,但具有相当复杂的解析递归,用于将 CSS 样式转换为 XSL FO 属性。