You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Apache-FOP模板实现PDF图片的2列3行网格布局?

问题描述

我正在使用Apache-FOP生成PDF文件,现有如下XSLT模板片段:

<xsl:template match="images">
    <xsl:apply-templates select="image"/>
</xsl:template>

<xsl:template match="image">
    <fo:block space-after="14px">
        <fo:external-graphic content-height="200pt" height="auto" width="auto"
                             src="url('data:{type};base64,{data}')"/>
    </fo:block>
</xsl:template>

对应的XML数据结构如下:

<images>
    <image>
        <type>image/png</type>
        <data>iVBORw0KGgoAAAANS...</data>
    </image>
    <image>
        <type>image/png</type>
        <data>iVBORw0KGgoAAAANS...</data>
    </image>
    <!-- ... more images -->
</images>

需要修改模板,使图片以2列3行的网格布局排列(每页展示6张图片),并相应调整图片尺寸。

解决方案

使用Apache FOP支持的fo:table实现网格布局,通过分组处理图片,确保每页容纳6张(2列×3行),同时适配图片尺寸:

修改后的XSLT模板如下:

<xsl:template match="images">
    <!-- 每6个图片分为一组,对应一页的6个位置 -->
    <xsl:for-each-group select="image" group-by="(position() - 1) idiv 6">
        <!-- 页面表格容器:占满页面宽度,无边框,设置内边距增加图片间距 -->
        <fo:table width="100%" border="0" cellpadding="8pt" cellspacing="0">
            <!-- 定义2列,宽度均分 -->
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-body>
                <!-- 每组内每2个图片为一行 -->
                <xsl:for-each-group select="current-group()" group-by="(position() - 1) idiv 2">
                    <fo:table-row>
                        <!-- 渲染当前行的图片 -->
                        <xsl:for-each select="current-group()">
                            <fo:table-cell text-align="center" vertical-align="middle">
                                <fo:block>
                                    <!-- 图片自适应单元格:宽度占满单元格,高度按比例缩放,避免溢出 -->
                                    <fo:external-graphic 
                                        width="100%" 
                                        height="auto" 
                                        content-width="scale-down-to-fit"
                                        content-height="scale-down-to-fit"
                                        src="url('data:{type};base64,{data}')"/>
                                </fo:block>
                            </fo:table-cell>
                        </xsl:for-each>
                        <!-- 若当前行只有1张图,补空单元格维持2列结构 -->
                        <xsl:if test="count(current-group()) = 1">
                            <fo:table-cell/>
                        </xsl:if>
                    </fo:table-row>
                </xsl:for-each-group>
            </fo:table-body>
        </fo:table>
        <!-- 每组(6张图)后添加分页符,确保下一组从新页开始 -->
        <fo:block break-after="page"/>
    </xsl:for-each-group>
</xsl:template>

关键调整说明

  • 网格布局逻辑:通过两次xsl:for-each-group分组,第一次按6张图分一页,第二次在页内按2张图分一行,配合2列表格实现2列3行的网格。
  • 图片尺寸适配:设置图片宽度为100%,高度自动按比例缩放,scale-down-to-fit确保图片不会超出单元格范围,避免变形或溢出。
  • 分页控制:每组图片后添加break-after="page",强制每页仅展示6张图片。
  • 单元格优化:设置cellpadding增加图片间的间距,text-align和vertical-align让图片在单元格内居中显示。

若需要固定图片高度(保证每行图片高度一致),可将fo:external-graphic的height设为固定值(如150pt),保留width="auto"和scale-down-to-fit即可。

内容的提问来源于stack exchange,提问作者maybesomename

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:15:10