как сохранить таблицу с заголовком, но разрешить разрывы страниц внутри тела таблицы в XSL-FO с использованием FOP

Я создаю PDF-файл, используя Apache FOP и таблицу стилей XSL-FO. В PDF я вывожу заголовки (html эквивалент h1), которые принадлежат таблице, поэтому их всегда следует хранить вместе. Однако мои таблицы также могут содержать так много данных, что они не обязательно помещаются на одной странице.

Желаемым результатом является набор правил, который позволяет сохранить заголовок вместе с таблицей и поместить оба на одной странице, если это возможно, но если данные таблицы настолько длинные, что не помещаются на одной странице, то разрывы страниц будут вставлены в таблицу, сохраняя при этом элемент заголовка на той же странице, что и начало таблицы.

Решение, которое у меня есть прямо сейчас, действительно объединяет заголовок и таблицу, но я получаю ошибку переполнения содержимого для данных таблицы, если все не помещается на одной странице. Я надеялся, что page-break-inside: избежать установки элемента таблицы поможет с этим, но, видимо, нет... предложений?

Пример xsl (обрезан для удобочитаемости):

<!-- add test table with header that should stay on same page -->
<fo:block font-size="20pt" font-weight="bold">Table header</fo:block>

<fo:table keep-with-previous.within-page="always"
      page-break-inside="avoid" 
      table-layout="fixed" border-width="1mm" border-style="solid">
  <fo:table-column column-width="auto" />
  <fo:table-column column-width="30mm" />

  <fo:table-header text-align="center" background-color="silver">
    <fo:table-row>
      <fo:table-cell padding="1mm" border-width="1mm" border-style="solid">
    <fo:block>First name</fo:block>
      </fo:table-cell>
      <fo:table-cell padding="1mm" border-width="1mm" border-style="solid">
    <fo:block>Last name</fo:block>
      </fo:table-cell>
    </fo:table-row>
  </fo:table-header>
  <fo:table-body>
    <!-- the table-rows can be repeated N times, spanning several pages -->
    <fo:table-row >
      <fo:table-cell padding="1mm" border-width="1mm" border-style="solid">
    <fo:block>ab</fo:block>
      </fo:table-cell>
      <fo:table-cell padding="1mm" border-width="1mm" border-style="solid">
    <fo:block>cd</fo:block>
      </fo:table-cell>
    </fo:table-row>
    <!-- .... more table-row:s ---> 

Обновление желаемого результата

Чтобы лучше описать, какой результат я ищу:

Результирующий документ содержит как текстовые абзацы, заголовки, так и таблицы.

  1. Если объем содержимого таков, что таблица будет иметь только одну или две строки на следующей странице, тогда xsl-fo должен переместить всю таблицу и заголовок на следующую страницу при условии, что он полностью помещается на этой странице.
  2. С другой стороны, если в таблице так много строк, что она все равно не помещается на совершенно новой странице, то вывод следует начинать сразу в потоке документа, при этом позволяя разделить таблицу на несколько страниц.

Если я удалю page-break-inside="avoid", я получу таблицу, которая красиво разбивается на несколько страниц, но случаи, описанные в #1, не будут сопоставляться. т.е. он не перемещает таблицу и полностью переходит на следующую страницу, если только несколько строк будут перемещены на следующую страницу. Если я оставлю разрыв страницы внутри, то у меня возникнет проблема переполнения содержимого с длинными таблицами, потому что строки, которые не помещаются на странице, не перемещаются на следующую страницу.

Я предполагаю, что одна из основных проблем заключается в том, что мои выходные таблицы очень динамичны по длине, и, к сожалению, у меня нет никакого контроля над тем, какой объем данных создается в таблицах.


person Jens Wegar    schedule 21.11.2011    source источник
comment
Я наверное что-то тут не так понял, но что не работает, если убрать page-break-inside: avoid?   -  person mzjn    schedule 21.11.2011
comment
@mzjn смотрите мой обновленный вопрос, надеюсь, это немного проясняет проблему?   -  person Jens Wegar    schedule 21.11.2011


Ответы (1)


Свойство CSS page-break-inside="avoid" сопоставляется с собственным свойством FO keep -вместе="всегда". Это сопоставление сомнительно IMO (но это другая история). В любом случае, я предлагаю вам использовать собственное свойство FO keep-together.within-column="1". вместо разрыва страницы внутри. Это позволяет Apache FOP проникать внутрь таблицы, когда это абсолютно необходимо.

person Jeremias Märki    schedule 22.11.2011
comment
Потрясающе, как раз то, что я искал. Спасибо! - person Jens Wegar; 23.11.2011
comment
@Jens Wegar: Мне любопытно, это действительно работает для вас (как случай № 1, так и № 2)? Я пытался использовать это решение, но для меня это решит только случай №1. Для длинных таблиц FOP (1.0), по-видимому, пытается сохранить вместе как можно большую часть таблицы, и начало таблицы переносится на следующую страницу. - person mzjn; 25.11.2011
comment
@mzjn: В тестах, которые я провел, решение дало то, что я ожидал. Но я слишком мало знаю о XSL-FO, чтобы быть уверенным, что это потому, что решение сработало, или это просто совпадение, что мои тесты прошли. Однако на данный момент решение Jeremias сработало, поэтому я пометил его как принятое. - person Jens Wegar; 30.11.2011