如何修改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
相关产品推荐
相关产品推荐

