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

嵌入超文本标记语言的PDF报告

夹谷岳
2023-03-14

我们有一个基于Java的系统,它从数据库中读取数据,用预设的XSL-FO标记合并单个数据字段,并用ApacheFOP将结果转换为PDF

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>

现在我正在寻找一种方法来允许一些字段包含静态超文本标记语言格式的内容。此内容将由我们启用超文本标记语言的编辑器(类似CLEditorCK编辑器等的东西)生成或从外部粘贴。

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

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

我有一个这样的代码的简单版本,并得到以下错误:

(错误位置未知)org . Apache . fo P1 . fo . validation exception:“{ http://www . w3 . org/1999/XSL/Format } table-body”不是“fo:block”的有效子级!(没有可用的上下文信息)

我的问题:

    < li >解决此问题的方法是什么? < li>Can

如果有人已经“在那里做过”,请分享你的经验。


共有2个答案

高建本
2023-03-14

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

在您的例子中,您显然有一个fo:table主体作为fo:block的子对象。不可能。fo:table主体只有一个有效的父级fo:table。您可能缺少fo:table标记,或者在此位置错误地插入了fo:table块。

在我看来,我可能会做一些稍微不同的事情。我会将XHTML内容内联到XSL FO中您想要的地方。然后我将创建一个身份转换,它复制所有基于fo的内容,但是使用XSL转换XHTML部分。这样,您实际上可以在像oXygen这样的XSL编辑器中单步执行转换,并查看错误发生的位置和原因。像其他品酒师一样。

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

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

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

王德华
2023-03-14
匿名用户

>

  • 如果使用 XSLT 调试器(如在 oXygen 或 XML Spy 中),则可以单步执行转换。对于oXygen - 不确定XML Spy或其他编辑器 - 如果您单击调试器输出中的标记,oXygen会突出显示来自生成该节点的源和样式表中的标记。

    一旦你有了FO,foeck框架(https://github.com/AntennaHouse/focheck)就有了目前可用的最完整的FO验证。

    < code>fo:block可以包含表格等。在XSL 1.1规范中,每个FO的定义都包括一个列出其允许内容的“内容”子部分。例如,参见http://www.w3.org/TR/xsl11/#fo_block.,内容模型中“参数实体”的定义见http://www.w3.org/TR/xsl11/#d0e6532,,但一些fo在其定义文本中有附加限制。

    你引用的文章似乎没有“用XPath提取根目录下的所有节点”这一步,我不知道你为什么需要它。除此之外,它看起来是使用Java完成这项工作的合理方法。

    您可以替换<code>

    如果字段内容的 FO 位于磁盘上,则使用 document() 非常简单。如果不是,则必须执行一些操作,例如重写 XSLT 处理器使用的 URIResolver,以便它执行正确的操作来检索内容,而不是在磁盘上查找。您甚至可以让 JTidying 作为检索 HTML 的 URIResolver 的一部分发生。您还可以在 URIResolver 内部进行转换为 FO,或者按照 @kevin-brown 的建议,将其作为单独的模式进行。如果转换是在 URIResolver 检索 FO 之前或期间完成的,那么模板引用对 FO 的“主要”转换只需要提取 FO 子文档的正确部分,例如 document('constructed-URI')/fo:root/fo:page-sequence/*。但是,如果您正在从天线屋修改样式表,那么无论如何,您应该能够修改它以不生成外部 fo:root 等。

    几年前,我也做过类似的事情,为基于XSLT的服务器重写libxslt XSLT处理器的URI解析器:内部XSLT处理器连续运行的上下文以特殊URI保存为文档,根本不必写入文件系统

    相反,您可以编写一个扩展函数来查找对字段的引用。例如,Print and Page Layout Community Group @ W3C已经为多个XSLT处理器生成了扩展函数,这些函数在XSLT转换过程中运行一个FO处理器,以获取格式化结果的区域树的XML。参见http://www.w3.org/community/ppl/wiki/XSLTExtensions

  •  类似资料:
    • 我正在使用ITextRenderer从html生成PDF。然而,我得到以下异常: 你能帮帮我吗? 任何帮助都将不胜感激。 先谢谢你。

    • 我的用例是我正在动态生成pdf。我也有一个单页的pdf。我想在现有的pdf页面之后/之前连接新生成的PDF。 我已经能够从超文本标记语言生成PDF(这可能导致2-3页)Pdf从超文本标记语言与CSS 我试图查找示例,其中之一是按页面方式连接现有的PDF使用现有的PDF-Concatenate

    • 我之所以发布这个问题,是因为许多开发人员或多或少地以不同的形式问同一个问题。我会自己回答这个问题(我是iText Group的创始人/首席技术官),这样它就可以成为“维基答案”如果堆栈溢出的“文档”特性仍然存在,那么这将是文档主题的一个很好的候选者。 我正在尝试将以下HTML文件转换为PDF: 在浏览器中,这种超文本标记语言如下所示: HTMLWorker根本不考虑CSS 当我使用时,我需要创建一

    • 我试图在HTML的pre标签中包装文本,但它不起作用。我使用下面的CSS作为我的标签。 我从如何在pre标记中换行文本? 我已添加

    • 我是新来的。我想解析html,但问题是我们必须在中指定的URL,我将在运行时从其他页面响应此URL。有没有办法将收到的网址传递到中?我读过这样的东西: 但是我不知道如何使用它。我很想知道是否有其他方法比jsoup更好。

    • 我正在通过maven jmeter插件成功地生成jmeter仪表板。我在Jenkins上配置了这个构建来运行,它还成功地生成了仪表板,显示了所有的图形/数据。我现在尝试用HTML发布器发布这个仪表板,这样就可以从Jenkins版本中访问它。该插件工作正常,将生成的仪表板和所有必要的文件夹/文件移动到存档位置,并在构建页面上显示指向索引的链接。html。 如果我点击那个链接,它会打开索引页面,但所有