如何检测使用 Apache FOP 呈现的 XSL-FO 文档中的溢出或换行符
How to detect overflow or line breaks in XSL-FO document rendered with Apache FOP
我有一个非常简单的FO文档:
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4">
<fo:region-body margin-top="30mm" />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block-container height="10mm" font-size="8mm" overflow="error-if-overflow" wrap-option="wrap">
<fo:block wrap-option="wrap">Hello W3Schools Hello W3Schools Hello W3Schools sad da sadasd dsaasd</fo:block>
</fo:block-container>
</fo:flow>
</fo:page-sequence>
</fo:root>
将 overflow
设置为 error-if-overflow
,我将在呈现此文档时遇到错误。有什么方法可以检测文本中溢出的位置吗?我希望能够手动将此文本分解为多个文本,但我不喜欢一次删除一个词并重新运行渲染以查看它是否再次失败的想法。
get 的异常是:
Content overflows the viewport of an fo:block-container in block-progression direction by 26078 millipoints. Content will be clipped. (See position 12:103)
不幸的是,这是发生错误的 block-container
标记的位置,而不是造成溢出的特定单词。
tl;dr 版本:
您可以使用 FOP's "intermediate format" feature 为生成的页面和区域创建 XML 表示,而不是创建 PDF 输出。
然后您可以将其用作
的输入
- 检查是否溢出
- 检查多少个字符(和/或哪个文本)将被放置在第一行,以便您可以修改手动输入文件
- 自动重写您的输入文件,以便将溢出的文本放在不同的块中(这将变得不那么琐碎)
更多详情:
您可以使用
从命令行创建区域树 (AT) 输出
fop input.fo -at application/pdf at.xml
或者您可以使用
创建中间格式 (IF) 输出
fop input.fo -if application/pdf if.xml
(FOP's site 详细介绍了如何使用 Java 代码以编程方式生成中间格式输出)。
例如,如果您的输入 FO 文件包含
<!--
there is no need for the wrap-option="wrap" attributes, as that is the default value,
I added an id attribute on the fo:block-container
-->
<fo:block-container id="foo" height="10mm" font-size="8mm" overflow="error-if-overflow">
<fo:block>Hello W3Schools Hello W3Schools Hello W3Schools sad da sadasd dsaasd</fo:block>
</fo:block-container>
IF 输出(比 AT 输出更简洁)是这样的:
...
<page index="0" name="1" page-master-name="A4" width="594720" height="792000">
<page-header/>
<content>
<viewport transform="translate(0,85039)" width="594720" height="706961">
<viewport width="594720" height="28346" clip-rect="0 0 594720 28346">
<font family="sans-serif" style="normal" weight="400" variant="normal" size="22677" color="#000000"/>
<id name="foo"/>
<text x="0" y="19400">Hello W3Schools Hello W3Schools Hello W3Schools sad</text>
<text x="0" y="46612">da sadasd dsaasd</text>
</viewport>
</viewport>
</content>
<page-trailer/>
</page>
...
XPath //viewport[id[@name = 'foo']]/text[1]
为您提供第一行的文本内容。
我有一个非常简单的FO文档:
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4">
<fo:region-body margin-top="30mm" />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block-container height="10mm" font-size="8mm" overflow="error-if-overflow" wrap-option="wrap">
<fo:block wrap-option="wrap">Hello W3Schools Hello W3Schools Hello W3Schools sad da sadasd dsaasd</fo:block>
</fo:block-container>
</fo:flow>
</fo:page-sequence>
</fo:root>
将 overflow
设置为 error-if-overflow
,我将在呈现此文档时遇到错误。有什么方法可以检测文本中溢出的位置吗?我希望能够手动将此文本分解为多个文本,但我不喜欢一次删除一个词并重新运行渲染以查看它是否再次失败的想法。
get 的异常是:
Content overflows the viewport of an fo:block-container in block-progression direction by 26078 millipoints. Content will be clipped. (See position 12:103)
不幸的是,这是发生错误的 block-container
标记的位置,而不是造成溢出的特定单词。
tl;dr 版本:
您可以使用 FOP's "intermediate format" feature 为生成的页面和区域创建 XML 表示,而不是创建 PDF 输出。
然后您可以将其用作
的输入- 检查是否溢出
- 检查多少个字符(和/或哪个文本)将被放置在第一行,以便您可以修改手动输入文件
- 自动重写您的输入文件,以便将溢出的文本放在不同的块中(这将变得不那么琐碎)
更多详情:
您可以使用
从命令行创建区域树 (AT) 输出fop input.fo -at application/pdf at.xml
或者您可以使用
创建中间格式 (IF) 输出fop input.fo -if application/pdf if.xml
(FOP's site 详细介绍了如何使用 Java 代码以编程方式生成中间格式输出)。
例如,如果您的输入 FO 文件包含
<!--
there is no need for the wrap-option="wrap" attributes, as that is the default value,
I added an id attribute on the fo:block-container
-->
<fo:block-container id="foo" height="10mm" font-size="8mm" overflow="error-if-overflow">
<fo:block>Hello W3Schools Hello W3Schools Hello W3Schools sad da sadasd dsaasd</fo:block>
</fo:block-container>
IF 输出(比 AT 输出更简洁)是这样的:
...
<page index="0" name="1" page-master-name="A4" width="594720" height="792000">
<page-header/>
<content>
<viewport transform="translate(0,85039)" width="594720" height="706961">
<viewport width="594720" height="28346" clip-rect="0 0 594720 28346">
<font family="sans-serif" style="normal" weight="400" variant="normal" size="22677" color="#000000"/>
<id name="foo"/>
<text x="0" y="19400">Hello W3Schools Hello W3Schools Hello W3Schools sad</text>
<text x="0" y="46612">da sadasd dsaasd</text>
</viewport>
</viewport>
</content>
<page-trailer/>
</page>
...
XPath //viewport[id[@name = 'foo']]/text[1]
为您提供第一行的文本内容。