Tabellen

Das im Publisher verwendete Tabellenmodell entspricht in den Grundzügen dem von HTML.

Grundlegender Aufbau einer Tabelle

Die Struktur einer Tabelle sieht wie folgt aus:

<PlaceObject>
  <Table>
    <Tr>
      <Td>...</Td>
      <Td>...</Td>
    </Tr>
    <Tr>
      <Td>...</Td>
      <Td>...</Td>
    </Tr>
  </Table>
</PlaceObject>

<Tr> steht für tablerow und <Td> für tabledata. Tabellen sind immer zeilenweise aufgebaut. Jede Zeile muss dieselbe Zahl an Spalten enthalten, ansonsten gibt der Publisher eine Fehlermeldung aus. Die Zahl der Zeilen hingegen ist beliebig.

Die Breite der Tabelle wird durch die Inhalte bestimmt. Bei Angabe von stretch="no" (Voreinstellung) beim Befehl <Table> nimmt die Tabelle nur die minimale Breite ein, bei stretch="max" wird die volle angegebene Breite (bzw. der maximal verfügbare Platz) genutzt.

<Layout xmlns="urn:speedata.de:2009/publisher/en"
  xmlns:sd="urn:speedata:2009/publisher/functions/en">
  <Trace grid="no" objects="yes"/>

  <Record element="data">
    <PlaceObject>
      <Table padding="2mm" stretch="no" >
        <Tr>
          <Td>
            <Paragraph><Value>Row 1 / Column 1</Value></Paragraph>
          </Td>
          <Td>
            <Paragraph><Value>Row 1 / Column 2</Value></Paragraph>
          </Td>
        </Tr>
        <Tr>
          <Td>
            <Paragraph><Value>Row 2 / Column 1</Value></Paragraph>
          </Td>
          <Td>
            <Paragraph><Value>Row 2 / Column 2</Value></Paragraph>
          </Td>
        </Tr>
      </Table>
    </PlaceObject>
  </Record>
</Layout>
Ein vollständiges Layout für eine Tabelle.
tablestretchmaxno

Bei stretch=“no” (bzw. weglassen des Attributs stretch) ist die Tabelle nur so breit, wie nötig (oben). Die Angabe von stretch=“max” bei der Tabelle hat zur Folge, dass die gesamte angegebene Breite genutzt wird. Die Voreinstellung für die Breite ist die Seitenbreite (unten).

Es gibt einige für die gesamte Tabelle gültige Einstellungen, wie die Schriftart, Innenabstand, Zeilen- und Spaltenabstand. Diese sind im Anhang in der Referenz für den Befehl <Table> beschrieben.

Tabellenzellen und Tabellenzeilen, Linien in Tabellen

Tabellenzeilen

Anweisungen in Tabellenzeilen (<Tr>) bestimmen Eigenschaften für alle Zellen in dieser Zeile, sofern sie nicht in der Zelle selber überschreiben werden. Z. B. legen align und valign die horizontale und vertikale Ausrichtung der Zellen fest. Dh. in der Zeile

<Tr align="left">
  <Td>...</Td>
  <Td>...</Td>
  <Td align="right">...</Td>
</Tr>

haben alle Spalten bis auf die letzte die Ausrichtung »linksbündig«.

In der Zeile kann auch die Hintergrundfarbe für die einzelnen Spalten festgelegt werden (backgroundcolor). Ebenso kann die minimale Höhe (minheight, Angabe in Rasterzellen bzw. einer Maßangabe) und der Abstand oberhalb der Zelle, sofern sie nicht auf einen Seitenumbruch folgt, festgelegt werden.

Zellen

Die Tabellenzellen (<Td>) haben umfangreiche Formatierungsmöglichkeiten. So kann der Innenabstand (padding) für jede der vier Seiten individuell festgelegt werden. Ebenso kann sich die Zellenumrandung (border) auf jeder Seite in Dicke und Farbe unterscheiden. Die Zellenumrandung liegt immer innerhalb einer Tabelle, mit der Ausnahme, dass bei benachbarten Zellen und der bei <Table> aktivierten Option border-collapse die Rahmen »überlappen«. Die Ausrichtung des Tabelleninhalts lässt sich über die Parameter valign (vertikal) und align (horizontal) festlegen.

Zellen können verschiedene Inhalte haben, auch gemischt:

  • Absätze (Paragraph, Block-Element)
  • Tabellen (Table, Block-Element)
  • Bilder (Image, Inline-Element)
  • Barcodes (Barcode, Inline-Element)
  • Kästchen (Box, Block-Element)
  • Mehrfachobjekte (Overlay, s.u., Inline-Element)
  • Vertikale Abstände (Vspace, s.u., Block-Element)
  • Rahmen (Frame, Block-Element)

In Tabellenzellen gibt es horizontale Objekte (Inline-Elemente) und vertikale Objekte (Block-Elemente). Das bezieht sich auf die Anordnung innerhalb der Tabellenzelle:

<PlaceObject>
  <Table width="8" stretch="max">
    <Tr align="center">
      <Td>
        <Image file="ocean.pdf" width="2"/>
        <Paragraph textformat="justified">
          <Value select="sd:dummytext()"/>
        </Paragraph>
        <Box width="2" height="1" backgroundcolor="green"/>
      </Td>
    </Tr>
  </Table>
</PlaceObject>
Eine Tabelle mit Inline- und Block-Elementen.
tab inline block

Block-Elemente in einer Tabellenzelle werden untereinander dargestellt.

Steht die Zeilenhöhe beispielsweise durch eine andere Zelle oder durch die Angabe von minheight im Zeilenanfang fest, so kann man mit VSpace einen vertikalen Leerraum einfügen. Damit wird der Teil oberhalb des Leerraums soweit wie möglich nach oben geschoben und der unter Teil nach unten, eine Angabe von valign in dieser Zelle hat dann keine Auswirkung mehr.

Linien

Zwischen einzelnen Zeilen können Linien gezeichnet werden.

<Table>
  <Tr>
     ...
  </Tr>
  <Tablerule rulewidth="3pt" color="green" />
</Table>

Die Angabe der Startspalte (startcolumn) ist möglich.

Colspan und Rowspan

Die natürliche Eigenschaft einer Tabelle ist, dass alle Zellen einer Zeile gleich hoch und alle Zellen in einer Spalte gleich breit sind. Zellen können sich aber über mehrere Spalten und Zeilen erstrecken. Die Anzahl der überdeckten Spalten wird mit colspan angegeben, die Voreinstellung ist hier 1. Die Anzahl der Zeilen wird mit rowspan angegeben, auch hier ist die Voreinstellung 1. Hier muss beachtet werden, dass die Summe der Spalten in einer Zeile der Gesamtzahl entspricht. Im nachfolgenden Beispiel enthält die zweite Zeile zwar nur zwei Zellen, diese erstreckt sich aber über zwei Spalten. Die dritte Zeile hat sogar nur eine Zelldefinition, der Rest der Zeile wird durch das zwei Zellen breite Bild aus der Zeile darüber belegt (rowspan="2").

<PlaceObject>
  <Table width="10"
    columndistance="3mm"
    leading="2mm">
    <Tr>
      <Td padding-bottom="2mm">
        <Paragraph><Value>1/1</Value></Paragraph>
      </Td>
      <Td padding-left="1mm">
        <Paragraph><Value>1/2</Value></Paragraph>
      </Td>
      <Td align="center">
        <Paragraph><Value>1/3</Value></Paragraph>
      </Td>
    </Tr>
    <Tr backgroundcolor="yellow">
      <Td>
        <Paragraph><Value>2/1</Value></Paragraph>
      </Td>
      <Td rowspan="2" colspan="2" >
        <Image width="5" file="ocean.pdf"/>
      </Td>
    </Tr>
    <Tr align="center">
      <Td>
        <Paragraph><Value>3/1</Value></Paragraph>
      </Td>
    </Tr>
  </Table>
</PlaceObject>
Ein etwas komplexeres Beispiel. Die Hintergrundfarbe des Bildes bestimmt sich aus der zweiten Zeile.
tab colspan rowspan

Auswirkung von rowspan und colspan

Angabe der Spaltenbreiten

In den bisherigen Beispiele werden die Breiten der Zellen automatisch durch den Inhalt bestimmt. Man kann auch die Spaltenbreiten fest vorgeben. Der Befehl dazu lautet Columns und wird direkt als erster Befehl innerhalb von Table angeführt:

<Table stretch="max">
  <Columns>
    <Column width="2mm"/>
    <Column width="1*"/>
    <Column width="3*"/>
  </Columns>
  <Tr>
    ...
  </Tr>
</Table>

Hier wird festgelegt, dass die Tabelle drei Spalten hat. Die erste Spalte hat eine Breite von 2mm, die zweite und die dritte Spalte teilen sich die übrige Breite im Verhältnis von 1 zu 3 auf. Im Befehl Column kann man noch weitere Angaben für die Spalte festlegen: die horizontale und vertikale Ausrichtung und die Hintergrundfarbe können vorgegeben werden. Eine Angabe bei einer Zelle überschreibt die Vorgabe.

Umbrüche in Tabellen

Ist die Tabelle zu hoch für die Seite, so umbricht sie und wird auf der nächsten Seite fortgesetzt. Dabei wird der noch zur Verfügung stehende Platz auf der aktuellen Seite und auf den Folgeseiten beachtet. Der Umbruch kann nach jeder Zeile eingefügt werden, sofern in der Zeile break-below nicht auf yes gesetzt ist. Einzelne Tabellenzellen werden nicht getrennt.

Bei dem Tabellenumbruch kann man eigene Kopf- und Fußzeilen einfügen, die auf jeder Seite wiederholt werden. Diese werden in den nächsten drei Abschnitten detailliert behandelt.

Kopf- und Fußzeilen (statisch)

Es gibt zwei Arten, in Tabellen Tabellenköpfe zu definieren. Die erste Variante wird in diesem Abschnitt vorgestellt. Sie eignet sich besonders, wenn der Tabellenkopf zu Beginn bekannt ist (statisch). Die zweite Variante eignet sich, wenn bestimmte Tabellenzellen als Kopfzeile dienen sollen (Abschnitte in Tabellen). Beide Varianten kann man auch kombinieren.

Ausgangspunkt ist eine einfache Tabelle:

<Layout xmlns="urn:speedata.de:2009/publisher/en"
  xmlns:sd="urn:speedata:2009/publisher/functions/en">

  <Record element="data">
    <PlaceObject>
      <Table>
        <Loop select="200">
          <Tr>
            <Td>
              <Paragraph>
                <Value>Tablecontents</Value>
              </Paragraph>
            </Td>
          </Tr>
        </Loop>
      </Table>
    </PlaceObject>
  </Record>
</Layout>

Die Kopfzeile definiert man in der Tabelle wie folgt (als Kindelement des Elements <Table>):

<Tablehead>
  <Tr backgroundcolor="gray">
    <Td>
      <Paragraph>
        <Value>Head</Value>
      </Paragraph>
    </Td>
  </Tr>
</Tablehead>

Man kann die Kopfzeile für die erste Seite separat definieren, in dem man das Attribut page spezifiziert (Voreinstellung ist all):

<Tablehead page="all"></Tablehead>

<Tablehead page="first"></Tablehead>
Schema für unterschiedliche Tabellenköpfe auf der ersten bzw. allen anderen Seiten. Die Reihenfolge der Deklaration ist nicht wichtig.

① Tabellenkopf für alle Seiten

② Wenn page="first" wie hier definiert wird, gilt die obige Definition (1) für alle Seiten, jedoch nicht für die erste Seite, denn hier gilt (2).

Mit dieser Variante kann man nicht nur den (sich wiederholenden) Tabellenkopf bestimmen, sondern auch den Tabellenfuß. Das geht analog zu <Tablehead>, nur dass die Seitenauswahl anstelle von first last erlaubt.

<Tablefoot page="last">
  <Tr backgroundcolor="gray">
    <Td>
      <Paragraph>
        <Value>Table foot last page</Value>
      </Paragraph>
    </Td>
  </Tr>
</Tablefoot>
<Tablefoot page="all">
  <Tr backgroundcolor="gray">
    <Td>
      <Paragraph>
        <Value>Table foot for all pages</Value>
      </Paragraph>
    </Td>
  </Tr>
</Tablefoot>

Tabellenköpfe und -füße müssen nicht nur aus einer Zeile bestehen. Sie können auch Linien und mehrere Zeilen enthalten.

Kopf- und Fußzeilen (dynamisch)

Im vorherigen Abschnitt wird der Tabellenkopf über <Tablehead> (und dem Gegenstück <Tablefoot>) erzeugt. Im Gegensatz dazu wird hier gezeigt, wie ein dynamischer Tabllenkopf erzeugt wird. Beide Varianten können kombiniert werden.

<Tr sethead="yes" backgroundcolor="lightgray">
  <Td>
    <Paragraph>
      <Value>New head</Value>
    </Paragraph>
  </Td>
</Tr>

Die »Magie« steckt in sethead="yes" in der Tabellenzeile. Dadurch wird diese Zeile auf der nächsten Seite ganz oben automatisch wiederholt, direkt unterhalb eines eventuell vorhandenen statischen Tabellenkopfs. Das eignet sich sehr gut für Zwischenüberschriften oder Abschnitte in Tabellen.

Beispiel

Ein etwas konstruiertes Beispiel. Es gibt zwei Abschnitte in der Tabelle mit zwei und acht Zeilen. Die Datei data.xml:

<data>
  <section name="section 1" rows="2"/>
  <section name="section 2" rows="8"/>
</data>

Das Layout gibt eine Tabelle aus, für jeden Abschnitt wird die Überschrift als Zeile ausgegeben, in der das Attribut sethead auf yes gesetzt ist. In einer Schleife werden die gewünschten Zeilen ausgegeben.

<Layout xmlns="urn:speedata.de:2009/publisher/en">
  <Pageformat width="100mm" height="60mm"/>

  <Record element="data">
    <PlaceObject>
      <Table padding="1mm" stretch="max">
        <ForAll select="section">
          <Tr sethead="yes" backgroundcolor="lightgray">
            <Td>
              <Paragraph>
                <Value select="@name"/>
              </Paragraph>
            </Td>
          </Tr>
          <Loop select="@rows" variable="i">
            <Tr>
              <Td>
                <Paragraph>
                  <Value select="concat('Row ', $i)"/>
                </Paragraph>
              </Td>
            </Tr>
          </Loop>
        </ForAll>
      </Table>
    </PlaceObject>
  </Record>
</Layout>
03 dyntabellenkopf

Die Abschnitte werden mit sethead="yes" markiert und werden im Tabellenkopf wiederholt.

Kopf- und Fußzeilen mit Übertrag

Manchmal möchte man in Tabellen in Kopf- bzw. Fußzeilen eine Zwischensumme bzw. Übertrag (engl. etwa »running sum«) ausgeben. Hier ist das Problem, dass das eine dynamische Information ist, die sich aus dem zur Verfügung stehenden Platz ergibt. Ist die Seite kürzer, so ist die Summe eine andere. Das heißt, dass man die Zahl nicht im Vorfeld als Kopf- oder Fußzeile definieren kann.

Dafür gibt es die Möglichkeit, Daten in einer Tabellenzeile zu speichern:

<Tr data="..." >

Diese Daten können später in Kopf- und Fußzeilen mit der speziellen Variablen $_last_tr_data abgefragt werden. Die Variable wird bei jeder Benutzung von data=".​.." überschrieben. Um dies zu illustrieren, gibt es ein vollständiges Layoutregelwerk, das diesen Mechanismus nutzt:

<Layout
  xmlns="urn:speedata.de:2009/publisher/en"
  xmlns:sd="urn:speedata:2009/publisher/functions/en">
  <Pageformat width="80mm" height="80mm" />

  <Record element="data">
    <!-- Wert für die erste Kopfzeile initialisieren -->
    <SetVariable variable="_last_tr_data" select="0"/>
    <SetVariable variable="sum" select="0"/>

    <PlaceObject>
      <Table stretch="max">
        <Tablehead>
          <Tr backgroundcolor="#eee">
            <Td>
              <Paragraph>
                <Value>Wert von $_last_tr_data: </Value>
                <Value select="$_last_tr_data"/>
              </Paragraph>
            </Td>
          </Tr>
        </Tablehead>
        <Loop select="100" variable="i">
          <SetVariable variable="sum" select="$sum + $i"/>
          <Tr data="$sum">
            <Td>
              <Paragraph>
                <Value select="concat('i = ',$i)"/>
              </Paragraph>
            </Td>
          </Tr>
        </Loop>
      </Table>
    </PlaceObject>
  </Record>
</Layout>
22 runningsum

Die berechneten Zwischensummen

Hier wird erst die Kopfzeile definiert, dann 100 Zeilen erzeugt (<Loop select="100">), die Schleifenzahl gespeichert und anschließend in jeder Zeile mit data="$sum" den errechneten Wert gespeichert, der später in der Kopfzeile ausgegeben wird.

Die Breite der dynamischen Kopf- und Fußzeile wird ohne $_last_tr_data berechnet. Das kann zu Problemen führen, wenn die neu errechnete Kopf- oder Fußzeile ein anderes Format hat.

Zusammenbauen von Tabellen

Tabellen werden manchmal nicht an einem Stück erzeugt. Ein gängiges Muster bei der Erstellung von Tabellen ist die Probe, ob eine Tabelle noch an einen bestimmten Platz passt. Dazu fügt man Zeile für Zeile an eine Tabelle an und platziert sie in eine Gruppe (eine virtuelle Fläche), um diese anschließend auszumessen. Das Vorgehen hierfür ist folgendes:

<SetVariable variable="tabellenzeilenneu">
  <Copy-of select="$tabellenzeilen"/>
  <Copy-of select="$diesezeile"/>
</SetVariable>

Wobei $diesezeile jeweils eine Tabellenzeile mit Start- und Endetag <Tr> .. </Tr> enthält und $tabellenzeilen leer ist oder mehrere Zeilen derselben Form enthält.

Geprüft wird nun, in dem die Tabelle in einer Gruppe erzeugt wird und anschließend z. B die Höhe der Gruppe überprüft wird:

<Group name="tbl">
  <Contents>
    <PlaceObject>
      <Table width="...">
        <Copy-of select="$tabellenzeilenneu"/>
      </Table>
    </PlaceObject>
  </Contents>
</Group>

<Switch>
  <Case test="sd:group-height('tbl') > ...">
    <!-- zu groß, Tabelle ohne die letzte Zeile ausgeben -->
    <PlaceObject>
      <Table width="...">
        <Copy-of select="$tabellenzeilen"/>
      </Table>
    </PlaceObject>
    <!-- letzte Zeile ist nun als Übertrag für die nächste Tabelle -->
    <SetVariable variable="tabellenzeilen">
      <Copy-of select="$diesezeile"/>
    </SetVariable>
  </Case>
  <Otherwise>
    <!-- passt, Tabelle ausgeben, Variable setzen -->
    <PlaceObject groupname="tbl"/>
    <SetVariable variable="tabellenzeilen">
        <Copy-of select="$tabellenzeilenneu"/>
    </SetVariable>
  </Otherwise>
</Switch>
Mit diesem Muster kann man eine Tabelle zeilenweise vergrößern und ausmessen

Eine etwas ausführlichere Beschreibung findet sich im Abschnitt Layoutoptimierung mithilfe von Gruppen.

Abwechselnde Zeilenfarben

Wechselnde Zeilenfarben werden häufig in Tabellen mit vielen Spalten benutzt, um eine Hilfe für das Auge beim Lesen der Tabelle zu geben. Die Zeilenfarbe kann man durch backgroundcolor=".​.." bei <Tr> angeben.

<Table>
  <Loop select="5" variable="i">
    <Tr backgroundcolor="{sd:alternating('tab', 'white', 'gray')}">
      <Td>
        <Paragraph>
          <Value>Zeile </Value>
          <Value select="$i"/>
        </Paragraph>
      </Td>
    </Tr>
  </Loop>
</Table>
Wechselnde Zeilenfarben. Das erste Argument der Funktion sd:alternating() ist eine Kennung, um verschiedene Alternierungen in einem Dokument zu unterscheiden.
tab wechselnde zeilenfarben

Abwechselnde Hintergrundfarben

Der Trick ist hier die Anwendung der Layoutfunktion sd:alternating(), die zwischen den Argumenten wechselt. Da das Attribut backgroundcolor einen festen Wert erwartet, muss mit den geschweiften Klammern in den »XPath-Modus« gesprungen werden.

Nach der Ausgabe der Tabelle ist nicht sichergestellt, dass beim nächsten Aufruf von sd:alternating() mit der Kennung tab wieder mit dem ersten Wert angefangen wird. Das kommt darauf an, welcher Wert zuletzt benutzt wurde. Um sicherzustellen, dass wieder bei dem ersten Wert angefangen wird, kann man bei Table das Attribut eval=".​.." nutzen:

<Table eval="sd:reset-alternating('tab')">
  ...
</Table>

Damit wird der Zähler für die angegebene Kennung (tab) zurückgesetzt.

Hintergrund in Tabellenzeilen

Text im Hintergrund

Mit den Attributen background-.​.. kann man Text in den Hintergrund legen.

<Table width="7">
  <Tr>
    <Td background-text="Neu"
      background-size="contain"
      background-textcolor="gray"
      background-transform="rotate(-40deg)">
      <Paragraph>
        <Value select="sd:loremipsum()"/>
      </Paragraph>
    </Td>
  </Tr>
</Table>
21 bgtext

Text im Hintergrund einer Zelle

Bild hinter dem Text

Mit dem Befehl <Overlay> kann man Elemente übereinander legen. In Tabellenzellen kann man das nutzen, um Text (wie Hinweise auf den Autor eines Bildes) über ein Bild zu legen. Man kann aber auch ganze Texte hinterlegen. Ob es sinnvoll ist, oder nicht, mag mal dahin gestellt sein.

<DefineFontfamily name="mini" fontsize="6" leading="8">
  <Regular fontface="TeXGyreHeros-Regular"/>
</DefineFontfamily>

<Record element="data">
  <PlaceObject>
    <Table width="7">
      <Tr>
        <Td>
          <Overlay>
            <Image width="4.5cm" file="_samplea.pdf"/>
            <Position x="100" y="10">
              <!-- Drehung um 90 Grad -->
                <Transformation matrix="0 1 -1 0 0 0"
                  origin-x="0" origin-y="100">
                  <Textblock width="4" fontface="mini">
                    <Paragraph textformat="left">
                      <Value>Foto: Reinhard M.</Value>
                    </Paragraph>
                  </Textblock>
                </Transformation>
            </Position>
          </Overlay>
        </Td>
      </Tr>
    </Table>
  </PlaceObject>
</Record>
21 overlay

Tabellenzelle mit Text und einem Bild im Hintergrund

Ausgleichen von Spalten

In der Regel benutzt eine Tabelle erst den ersten Positionierungsrahmen eines Bereichs, dann den nächsten etc.

Schaltet man nun bei <Table balance="yes">, so wird die Tabelle wie folgt ausgegeben:

Damit das funktioniert, muss die Tabelle in einem Platzierungsbereich ausgegeben werden, nicht auf einer Seite. Die Anzahl der Spalten, auf die ausgeglichen werden soll, bestimmt sich durch die Anzahl der Platzierungsrahmen, die der Bereich enthält. Hier ein konkretes Beispiel:

<Layout xmlns="urn:speedata.de:2009/publisher/en"
  xmlns:sd="urn:speedata:2009/publisher/functions/en"
  version="3.1.24">
  <Trace grid="yes"/>
  <SetGrid nx="2" dx="5mm" height="12pt"/>
  <Pageformat width="140mm" height="100mm"/>
  <Pagetype name="Seite" test="true()">
    <Margin left="1cm" right="1cm" top="1cm" bottom="1cm"/>
    <PositioningArea name="zweispalten">
      <PositioningFrame width="1" height="{sd:number-of-rows()}" row="1" column="1"/>
      <PositioningFrame width="1" height="{sd:number-of-rows()}" row="1" column="2"/>
    </PositioningArea>
  </Pagetype>

  <Record element="data">
    <PlaceObject area="zweispalten">
      <Table balance="no">
        <Loop select="20" variable="i">
          <Tr>
            <Td><Paragraph><Value>Row </Value><Value select="$i"/></Paragraph></Td>
          </Tr>
        </Loop>
      </Table>
    </PlaceObject>
  </Record>
</Layout>

Mit balance="no" wie im Beispiel gibt es eine volle erste Spalte:

Setzt man hingegen balance="yes", so wird daraus:

Die Angabe wird immer auf der letzte Seite einer Tabelle beachtet, da die vorherigen Seiten den Platz sowieso vollständig ausfüllen.

Seitenwechsel in Tabellen

Ist eine Tabelle größer als der zur Verfügung stehende Platz auf der Seite, so wird die Tabelle auf der nächsten Seite bzw. im nächsten Platzierungsrahmen fortgeführt. Um solch einen Seitenwechsel zu erzwingen, gibt es den Befehl <TableNewPage>.