# Tabellen mit XSL-FO



## Alenka87 (19. Dez 2011)

Guten Morgen Forum 

ich häng grad an einem XSL-FO Problem weiss allerdings nicht ob es überhaupt lösbar ist und in welche Richtung ich recherchieren sollte.

Es geht um Tabellengestaltung mit XSL-FO. Ich habe eine riesige Tabelle mit sehr viele Spalten, die ausgedruckt werden muss. Problem: Es sind zu viele Spalten für das Papierformat.
Nun suche ich nach einer Möglichkeit, dass die Tabelle automatisch auf der anderen Seite bzw. auf dem nächsten Blatt fortgeführt wird.
Dabei muss natürlich irgendwie ausgerechnet werden wieviel Platz für die Spalten tatsächlich da ist, wieviele Spalten auf eine Seite/Blatt passen, ab welcher Spalte die Tabelle auf dem anderen Blatt/anderer Seite fortgeführt werden muss....???:L kann man das irgendwie über Seitengestaltung machen oder gibt es für so was irgendeine adnere Lösung?

Ich weiss nicht ob ich das richtig erklären konnte, daher eine kleine Skizze


----------



## SlaterB (19. Dez 2011)

du kannst alles in eine Tabelle stecken, wird automatisch auf mehrere Seiten umgebrochen,
alle Zeilen, die nicht im table:body sondern im table:header stehen, werden auf neuen Seiten wiederholt,

vorher selber ausrechnen/ getrennte Sublisten anzulesen ist natürlich eine Alternative, 
habe ich selber gerade gemacht um jeweils zwei Listen auf eine Seite anzuzeigen, danach sah dein Bild zuerst aus,

ich fürchte irgendwelche automatischen Hinweise wie Zeilenhöhe, benötigte mehrzeilige Zeilen usw. wird es dazu nicht geben, 
muss man alles selber vorher in Java aus den Daten heraus berechnen und eben mit Schriftgröße/ Anzahl Zeilen pro Seite
experimentieren

edit: ok, ich sehe gerade dass es um viele Spalten statt viele Zeilen geht, dann befürchte ich die Rechnen-Variante, ja,
aber kann natürlich nichts ausschließen was ich selber vielleicht nur nicht kenne


----------



## Alenka87 (19. Dez 2011)

Ich hab ziemlich viel herumexperementiert. Wenn ich zu viele Zeilen habe, klar, die gehen dann auf der nächsten Seite weiter. Und der Header wiederholt sich. 

Aber  wenn ich zu viele SPalten habe, werden diese einfach abgeschnitten.

Nun suche ich nach Mechanismen, die es ermöglichen, dass die Spalten, die nicht mehr reinpassen nicht abgeschnitten, sondern auf der nächsten Seite fortgeführt werden. Genauso wie bei zu vielen Zeilen.

Aber gibt es so was überhaupt?!?!?
Und wenn es so was nicht gibt, wie kann ich das Problem angehen? ;(


----------



## SlaterB (19. Dez 2011)

tja, ob es das gibt,
hab bisher bei google bisschen geschaut,

eine ähnliche unbeantwortete Frage aus 2003 (..)
wide tables from Luke on 2003-12-18 (www-xsl-fo@w3.org from December 2003)
liefert zwar den schönen umfassenden Suchbegriff "spanning wide tables across pages",
ist allerdings auch das bisher einzige Ergebnis zu einer dann genauen Suche.., selbst ohne Einschränkung auf 'xsl fo',
bestimmt ist dieser Forum-Thread hier dann auch bald ein zweites Ergebnis

-----

die Berechnung/ Strukturierung sollte grundsätzlich überschaubar sein, wie hast du denn bisher die Daten übergeben?
grundsätzlich ist da zwischen eher allgemeinen Ansatz, der dann auch für beliebige Tabellen funktioniert,
und eher vorgegebener Struktur zu unterscheiden,

ganz allgemein könntest du alle Daten, selbst die Spaltenbreiten, geordnet als Listen übergeben,
welche dann mit einer Art Schleifenverarbeitung (z.B. durch Rekursion) im XSL abgearbeitet wird,
doch reichlich aufwendig, aber machbar, 
dann ist es eine reine Java-Frage, die Tabelle beliebig nach Spalten oder Zeilen aufzutrennen 
und alles was zusammengehört als jeweils eine Datenliste zu übergeben,

----

falls du dich dagegen nur um eine/ wenige Tabellen kümmern musst und das meiste eh schon im XSL steht, könntest du das relativ leicht auftrennen,
wie sieht dein Code/XSL bisher aus?
anstelle der bisherigen Tabellendefinition kommen neue Unter-Aufrufe bzw. eben zwei Tabellendefinitionen:

- call-template tabelleA
- wahrscheinlich Seitenumbruch erzwingen
- call-template tabelleB

die Tabellen werden genau so definiert, wie sie auf den jeweiligen Seiten aussehen sollen, 
Zugriff auf die nur einmal vorhandenen Daten sollte wie vorher funktionieren

spannender wird es, wenn es mehr als eine Seite von beiden Arten werden soll und diese sich abwechseln müssen,
oder was immer an Spezialitäten dazukommt,

ich rede jetzt eigentlich schon viel zu viel, was konkret ist deine Frage? falls du dich überhaupt zu solchen Kleinkram entschließt,
aber ich persönlich kann nichts anderes nennen


----------



## Alenka87 (19. Dez 2011)

so sieht meien XML sehr vereinfacht aus:

[XML]<info>

   <metadaten>

      <visible>
         <id>false</id>
         <name>true</name>
         <number>true</number>
      </visible>

      <placement>
         <id>0</id>
         <name>1</name>
         <number>2</number>
      </placement>
   </metadaten>

   <items>

      <item id="1">
         <name>item1</name>
         <number>324</number>
      </item>

      <item id="2">
         <name>item2</name>
         <number>326</number>
      </item
   </items>
<info>[/XML]


Nur dass da noch ca. 20 weitere Spalten hinzukommen und noch ganz viele "Items" 

Ich habe ein Template für "table" dass drei weitere Templates aufruft.
1) ein tempalte um zu berechnen wieviele "columns" überhaupt notwendig sind" 
An dieser Stelle wird auch nachgeschaut, in welcher Reiehnfolge die angezeigten Spalten sein müssen und table-column wird sofort mit der passenden width="xxx" aufgerufen.
2) Tempalte dass den header gestaltet. Dabei ist natürlich die Reiehnfolge des Spalten entscheident
3) zuletzt das Template dass dann den table-body erzeugt

und nun häng ich an dem problem dass die Spalten die nicht reinpassen, rechts abgeschnitten werden 

hab überlegt irgendwie auszurechnen wieviele Spalten reinpassen und dann eben mehrere Tables zu erstellen. Aber das dürfte auch recht kompliziert sein, oder?!


Werd jetzt mal denk Link durchlesen denn du gefunden hast, danke


----------



## SlaterB (19. Dez 2011)

im Link wird nicht viel drinstehen

> ein tempalte um zu berechnen wieviele "columns" überhaupt notwendig sind" 
im XSL wird das gemacht?
kann ich mir kaum vorstellen,
mache mehr in Java. übergib alles in Daten als XSL


----------



## Alenka87 (19. Dez 2011)

[XML]<xsl:template name="getColumn">
	<xsl:call-template name="getColumnOrder">
		<xsl:with-param name="orderWidth" select="1"/>
	</xsl:call-template>
	<xsl:call-template name="getColumnOrder">
		<xsl:with-param name="orderWidth" select="2"/>
	</xsl:call-template>
        <!-- usw. -->
</xsl:template>

<xsl:template name="getColumnOrder">
	<xslaram name="orderWidth"/>
	<xsl:choose>
		<xsl:when test="info/meta/visible/id = 'true' ">
			<xsl:choose>
				<xsl:when test="$orderWidth = $id_placement">
					<fo:table-column column-width="10mm"/>
				</xsl:when>
			</xsl:choose>
		</xsl:when>
	</xsl:choose>
	<xsl:choose>
		<xsl:when test="info/meta/visible/name = 'true' ">
			<xsl:choose>
				<xsl:when test="$orderWidth = $name_placement">
					<fo:table-column column-width="40mm"/>
				</xsl:when>
			</xsl:choose>
		</xsl:when>
	</xsl:choose>
        <!-- usw. -->
</xsl:template>[/XML]


Und die Werte für visible/name, visible/id, ..., placement/id, placement/name, ... werden natürlich über Java eingetragen


----------



## SlaterB (19. Dez 2011)

schick, aber noch mehr Untermethoden wären dort gar nicht schlecht,

[xml]
<xsl:template name="getColumnOrder">
    <xsl:call-template name="xy">
        <xsl:with-param name="orderWidth" select="$orderWidth"/>
        <xsl:with-param name="col" select="info/meta/visible/id"/> 
        <xsl:with-param name="w" select="10"/> 
    </xsl:call-template>
     usw.
[/xml]
könnten es noch kürzer darstellen 

-----

von Ausführung dieser Methoden erhälst du aber nur fo:table-column-Definitionen,
keine Information für die weitere Verarbeitung, welche Werte etwa in jeder Zeile anzuzeigen sind?
die  Reihenfolge steckt in $id_placement usw., das ist im XSL definiert oder wird das ausgelesen?

das wäre noch bisschen spannender, besonders ob wirklich irgendwo 'berechnet wird wieviele "columns" überhaupt notwendig sind' 

wer entscheidet im Moment?

dort wo derzeit 5, 3, 7, 8, 12, 1, 4 vorgegeben wird, auf welche Weise auch immer (fest oder berechnet?)
dort muss stattdessen eben 5, 3, 7, 8 für die erste Seite und 12, 1, 4 für die zweite rauskommen,

die Verarbeitung sich danach richten dass zwei Tabellen rauskommen,
kann natürlich komplizierter sein als so in 1-2 Sätzen


----------



## Alenka87 (19. Dez 2011)

ok, ich versuche dir zu folgen und deine idee weiter auszubauen....

ich habe eine xml datei mit ganz vielen _"Items"_... und einem Knoten _"Metadaten"_, der zwei Childknoten hat...

[XML]<metadaten>
   <visible>
      <id>false</id>
      <name>true</name>
      <nummer>true</nummer>
      <datum>true</datum>
      <info1>true</info1>
      <info2>true</info2>
   </visible>
   <placement>
   <id>0</id>
      <name>1</name>
     <nummer>2</nummer>
      <datum>4</datum>
      <info1>5</info1>
      <info2>3</info2>
   </placement>
   <items>
      <!-- ... -->
   </items>[/XML]


Die Strktur mit Metadaten, Placement, Visible ist vorgegeben. Die Werte werden mittels Java übergeben.

Wenn ich mit count tatsächlich zähle wievieel Splaten angezeigt werden, komme ich bei diesem Beispiel auf 5 Spalten in der Reihenfolge: Name, Nummer, info2, datum, info1
Sagen wir mal, dann auf eine Seite nur Name und Nummer passen.... 
Mit Java kann ich die Breite der Spalten übergeben.
Wenn ich irgendwie irgendwo vermerken könnte, dass nur Name und Nummer auf eine Seite passen... könnte ich auch für die restlichen Spalten quasi neue Tabelle erzeugen. Aber dann bräcuhte ich den "page-break" und der geht nicht  _property - "page-break-after" is not implemented yet._ ...
whaaaaa....


----------



## SlaterB (19. Dez 2011)

ja, den placement-Block solltest du irgendwie in zwei aufspalten, 
falls jeder für sich wie bisher verarbeitet wird bzw. in einem Gesamtdurchlauf eingebunden wird, kommen vielleicht zwei Tabellen raus

ich benutze zum Seitenumbruch
<fo:block break-before="page"/>


----------

