阿帕奇 FOP |多页 table 行高问题
Apache FOP | Multi page table row height issue
我正在使用 Apache FOP XSL 文件格式生成 PDF。
我的要求是
- PDF 格式的表格数据
- Table 尺寸很大,所以 Same table 扩展到多个页面(宽度方面,第一页的几列其他在下一页)
- 第 1 页有 3 列(C1、C2、C3)
- 第 2 页有 5 列(C4、C5、C6、C7、C8)
- 少数单元格可能有多行数据
问题描述:
- 当Page-2第4行第4列有多行数据时,其行高根据内容增加
- 但在第 1 页中,第 4 行的行高为单行。
当任何单元格数据是任何页面的多行时,我希望同一 table 的所有页面具有相同的行高。
如果需要,这里是 XSL 文件:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<!-few params declaration->
<xsl:template match="/rs">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="data-template-1" page-height="11.0in" page-width="17.0in"
margin-top="0.5in" margin-bottom="1.0in" margin-left="0.5in"
margin-right="0.5in">
<fo:region-body margin-top="1.5in" margin-bottom="0.8in"/>
<fo:region-before extent="0.7in"/>
<fo:region-after/>
</fo:simple-page-master>
<fo:simple-page-master master-name="data-template-2" page-height="11.0in" page-width="17.0in"
margin-top="0.5in" margin-bottom="1.0in" margin-left="0.5in"
margin-right="0.5in">
<fo:region-body margin-top="1.5in" margin-bottom="0.8in"/>
<fo:region-before extent="0.7in"/>
<fo:region-after/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:for-each select="rb">
<xsl:variable name="current-initial-page-number" select="$param.initialPageNumber + (position() * $pagesPerTable)" />
<fo:page-sequence master-reference="data-template-1" initial-page-number="{$current-initial-page-number}"
font-size="{$cdrFontSize}" font-family="{$cdrFontFamily}" line-height="10.2pt">
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed" width="100%" space-after.optimum="{$cdrInfoTableSpaceAfter}" border-width="0.4mm" border-style="solid">
<fo:table-column column-width="23.1mm"/>
<fo:table-column column-width="23.1mm"/>
<fo:table-column column-width="18.9mm"/>
<fo:table-header text-align="center" display-align="center">
<fo:table-row font-weight="bold" background-color="rgb(230,230,230)">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C1'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C2'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C3"/>
</xsl:call-template>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<xsl:for-each select="r">
<fo:table-row text-align="left" display-align="before">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C1']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C12']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C3']"/>
</xsl:call-template>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="data-template-2"
font-size="{$cdrFontSize}" font-family="{$cdrFontFamily}" line-height="10.2pt">
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed" width="100%" space-after.optimum="{$cdrInfoTableSpaceAfter}" border-width="0.4mm" border-style="solid">
<fo:table-column column-width="88.2mm"/>
<fo:table-column column-width="88.2mm"/>
<fo:table-column column-width="48.3mm"/>
<fo:table-column column-width="23.1mm"/>
<fo:table-column column-width="54.6mm"/>
<fo:table-header text-align="center" display-align="center">
<fo:table-row font-weight="bold" background-color="rgb(230,230,230)">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C4'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C5'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C6'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C7'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C8'"/>
</xsl:call-template>
</fo:table-row>R
</fo:table-header>
<fo:table-body>
<xsl:for-each select="r">
<fo:table-row text-align="left" display-align="before">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C4']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C5']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C6']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C7']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C8']"/>
</xsl:call-template>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</fo:root>
</xsl:template>
<xsl:template name="cdr_table_cell">
<xsl:param name="cellValue"/>
<fo:table-cell border-width="0.4mm" border-style="solid">
<fo:block-container overflow="hidden">
<fo:block margin-left="0.5mm" margin-top="0.3mm">
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$cellValue"/>
</xsl:call-template>
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:template>
<!-- The following templates are used to add empty space character to data, so that FOP can break (wrap) the word -->
<xsl:template name="zero_width_space_1">
<xsl:param name="data"/>
<xsl:param name="counter" select="0"/>
<xsl:choose>
<xsl:when test="$counter <= string-length($data)">
<xsl:value-of select='concat(substring($data,$counter,1),"​")'/>
<xsl:call-template name="zero_width_space_2">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="counter" select="$counter+1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="' '"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="zero_width_space_2">
<xsl:param name="data"/>
<xsl:param name="counter"/>
<xsl:value-of select='concat(substring($data,$counter,1),"​")'/>
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="counter" select="$counter+1"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
我不想要的
- 修复了行高,因为它会浪费页面 space,即使所有数据都集中在一行中。
格式化完整 table 两次:每页一次。
对于 table 的第一个副本,将第 3 列之后的所有内容设为白色或透明。
对于 table 的第二个副本,将第 1 至 3 列中的所有内容设为白色或透明,并在 table 上添加负边距(并在table 个单元格),以便第 1 至 3 列位于页面左侧。
请注意,如果您使用的是 AH Formatter,则可以使用 Spread Page Master 扩展(请参阅 https://www.antenna.co.jp/AHF/help/v70e/ahf-spread.html)并创建一个跨越两个页面的区域。
我正在使用 Apache FOP XSL 文件格式生成 PDF。
我的要求是
- PDF 格式的表格数据
- Table 尺寸很大,所以 Same table 扩展到多个页面(宽度方面,第一页的几列其他在下一页)
- 第 1 页有 3 列(C1、C2、C3)
- 第 2 页有 5 列(C4、C5、C6、C7、C8)
- 少数单元格可能有多行数据
问题描述:
- 当Page-2第4行第4列有多行数据时,其行高根据内容增加
- 但在第 1 页中,第 4 行的行高为单行。
当任何单元格数据是任何页面的多行时,我希望同一 table 的所有页面具有相同的行高。
如果需要,这里是 XSL 文件:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<!-few params declaration->
<xsl:template match="/rs">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="data-template-1" page-height="11.0in" page-width="17.0in"
margin-top="0.5in" margin-bottom="1.0in" margin-left="0.5in"
margin-right="0.5in">
<fo:region-body margin-top="1.5in" margin-bottom="0.8in"/>
<fo:region-before extent="0.7in"/>
<fo:region-after/>
</fo:simple-page-master>
<fo:simple-page-master master-name="data-template-2" page-height="11.0in" page-width="17.0in"
margin-top="0.5in" margin-bottom="1.0in" margin-left="0.5in"
margin-right="0.5in">
<fo:region-body margin-top="1.5in" margin-bottom="0.8in"/>
<fo:region-before extent="0.7in"/>
<fo:region-after/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:for-each select="rb">
<xsl:variable name="current-initial-page-number" select="$param.initialPageNumber + (position() * $pagesPerTable)" />
<fo:page-sequence master-reference="data-template-1" initial-page-number="{$current-initial-page-number}"
font-size="{$cdrFontSize}" font-family="{$cdrFontFamily}" line-height="10.2pt">
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed" width="100%" space-after.optimum="{$cdrInfoTableSpaceAfter}" border-width="0.4mm" border-style="solid">
<fo:table-column column-width="23.1mm"/>
<fo:table-column column-width="23.1mm"/>
<fo:table-column column-width="18.9mm"/>
<fo:table-header text-align="center" display-align="center">
<fo:table-row font-weight="bold" background-color="rgb(230,230,230)">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C1'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C2'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C3"/>
</xsl:call-template>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<xsl:for-each select="r">
<fo:table-row text-align="left" display-align="before">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C1']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C12']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C3']"/>
</xsl:call-template>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="data-template-2"
font-size="{$cdrFontSize}" font-family="{$cdrFontFamily}" line-height="10.2pt">
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed" width="100%" space-after.optimum="{$cdrInfoTableSpaceAfter}" border-width="0.4mm" border-style="solid">
<fo:table-column column-width="88.2mm"/>
<fo:table-column column-width="88.2mm"/>
<fo:table-column column-width="48.3mm"/>
<fo:table-column column-width="23.1mm"/>
<fo:table-column column-width="54.6mm"/>
<fo:table-header text-align="center" display-align="center">
<fo:table-row font-weight="bold" background-color="rgb(230,230,230)">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C4'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C5'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C6'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C7'"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="'C8'"/>
</xsl:call-template>
</fo:table-row>R
</fo:table-header>
<fo:table-body>
<xsl:for-each select="r">
<fo:table-row text-align="left" display-align="before">
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C4']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C5']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C6']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C7']"/>
</xsl:call-template>
<xsl:call-template name="cdr_table_cell">
<xsl:with-param name="cellValue" select="c[@n='C8']"/>
</xsl:call-template>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</fo:root>
</xsl:template>
<xsl:template name="cdr_table_cell">
<xsl:param name="cellValue"/>
<fo:table-cell border-width="0.4mm" border-style="solid">
<fo:block-container overflow="hidden">
<fo:block margin-left="0.5mm" margin-top="0.3mm">
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$cellValue"/>
</xsl:call-template>
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:template>
<!-- The following templates are used to add empty space character to data, so that FOP can break (wrap) the word -->
<xsl:template name="zero_width_space_1">
<xsl:param name="data"/>
<xsl:param name="counter" select="0"/>
<xsl:choose>
<xsl:when test="$counter <= string-length($data)">
<xsl:value-of select='concat(substring($data,$counter,1),"​")'/>
<xsl:call-template name="zero_width_space_2">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="counter" select="$counter+1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="' '"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="zero_width_space_2">
<xsl:param name="data"/>
<xsl:param name="counter"/>
<xsl:value-of select='concat(substring($data,$counter,1),"​")'/>
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="counter" select="$counter+1"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
我不想要的
- 修复了行高,因为它会浪费页面 space,即使所有数据都集中在一行中。
格式化完整 table 两次:每页一次。
对于 table 的第一个副本,将第 3 列之后的所有内容设为白色或透明。
对于 table 的第二个副本,将第 1 至 3 列中的所有内容设为白色或透明,并在 table 上添加负边距(并在table 个单元格),以便第 1 至 3 列位于页面左侧。
请注意,如果您使用的是 AH Formatter,则可以使用 Spread Page Master 扩展(请参阅 https://www.antenna.co.jp/AHF/help/v70e/ahf-spread.html)并创建一个跨越两个页面的区域。