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

基于ERB模板的PDF导出:列表对齐与分页问题求助

ERB模板生成PDF的排版问题解决方案

核心问题与需求

动态渲染内容通过ERB生成PDF时,遇到排版矛盾:

  • 编号需与h2标题同行,标题换行后要对齐编号下方
  • 标题不能跨页拆分
  • 标题与对应第一段不能被分页隔开
  • 尝试调整block、page-break、list-style-position等CSS属性后,解决一个问题会引发另一个(比如改block后分页问题仍存在,用div包裹导致对齐混乱、编号全为0)

实际渲染段落的ERB代码:

<% point_content.call(key.to_s.delete_suffix('_title'), price_list_variant).each do |paragraph| %>
  <p><%= paragraph %></p>
<% end %>

分步解决方案及原理

1. 实现编号与标题同行+换行对齐

放弃默认列表编号,改用CSS计数器+Flex布局控制:

/* 初始化计数器 */
.content-container {
  counter-reset: section-counter 0;
}

/* 标题容器:控制编号与标题布局 */
.title-wrapper {
  counter-increment: section-counter;
  display: flex;
  align-items: flex-start;
  margin: 1em 0;
}

/* 自定义编号 */
.title-wrapper::before {
  content: counter(section-counter) ".";
  margin-right: 0.5em;
  flex-shrink: 0; /* 编号固定宽度,不被挤压 */
}

/* 标题样式 */
.title-wrapper h2 {
  flex: 1; /* 标题占满剩余宽度,换行时自动对齐编号下方 */
  margin: 0;
  line-height: 1.5;
}

原理:默认列表的list-style-position无论设inside还是outside,都无法完美解决换行对齐问题。Flex布局将编号(伪元素)和标题拆分为两个独立的Flex项,flex-shrink:0保证编号不被压缩,flex:1让标题自动填充剩余空间,换行时自然对齐编号下方。

2. 禁止标题跨页+标题与第一段不分离

将标题和对应第一段包裹在同一个容器中,配合分页控制CSS:

/* 标题+段落的分组容器,阻止内部内容跨页 */
.section-group {
  page-break-inside: avoid;
}

/* 禁止标题单独留在页尾 */
.title-wrapper h2 {
  page-break-after: avoid;
}

调整ERB代码,将标题与对应段落的循环包裹在分组容器内:

<div class="content-container">
  <% # 假设point_content是包含标题和对应段落的键值对集合 %>
  <% point_content.each do |title_key, paragraphs| %>
    <div class="section-group">
      <div class="title-wrapper">
        <h2><%= title_key.delete_suffix('_title') %></h2>
      </div>
      <% paragraphs.each do |paragraph| %>
        <p><%= paragraph %></p>
      <% end %>
    </div>
  <% end %>
</div>

原理:page-break-inside: avoid会让浏览器尽量保持容器内的内容在同一页,避免标题和第一段被分页拆分;page-break-after: avoid防止标题刚好落在页尾,下一段被迫跑到下一页。之前用div包裹出问题,是因为没有正确设置计数器的层级(计数器未在父容器初始化),且布局逻辑混乱导致编号未正确递增。

3. 修复编号全为0的问题

确保计数器的counter-reset在所有标题容器的共同父元素上(比如上述的.content-container),同时counter-increment在每个标题容器(.title-wrapper)上。这样每个标题容器都会触发计数器递增,避免出现编号为0的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:37:36