Tableaux en PDF avec sauts de page horizontaux

Est-ce que quelqu’un connaît un moteur de présentation PDF (de préférence open-source) pour Java, capable de rendre des tables avec des sauts de page horizontaux? Le “saut de page horizontal” correspond au moins au nom de la fonctionnalité dans BIRT, mais il faut préciser: si un tableau comporte trop de colonnes pour tenir sur la largeur de page disponible, je souhaite qu’il soit divisé horizontalement sur plusieurs Tableau à 10 colonnes, les colonnes 1 à 4 sont affichées sur la première page et les colonnes 5 à 10 sur la deuxième page. Cela devrait bien sûr être répété sur les pages suivantes, si le tableau comporte trop de lignes pour s’installer verticalement sur une page.

Jusqu’à présent, il a été très difficile de rechercher des produits. Je pense qu’une telle fonctionnalité peut être nommée différemment dans d’autres produits, ce qui rend difficile l’utilisation de la tante Google pour trouver une solution appropriée.

Jusqu’à présent, j’ai essayé:

Comme il semble y avoir des dizaines d’autres moteurs de rapports ou de mise en page qui peuvent ou non s’adapter et que j’ai un peu de mal à deviner exactement ce qu’il faut chercher, j’espérais que quelqu’un avait peut-être déjà les mêmes exigences une suggestion dans la bonne direction. Il est relativement important que le produit puisse être facilement intégré dans une application de serveur Java, une bibliothèque Java native serait idéale.

Disposition attendue

Maintenant, pour que les lignes restnt alignées sur toutes les pages, les hauteurs de lignes doivent être calculées comme suit:

Row1.height = max(A1.height, B1.height, C1.height, D1.height) Row2.height = max(A2.height, B2.height, C2.height, D2.height) 

Bien que BIRT semble actuellement faire quelque chose comme:

 Page1.Row1.height = max(A1.height, B1.height) Page2.Row1.height = max(C1.height, D1.height) Page1.Row2.height = max(A2.height, B2.height) Page2.Row2.height = max(C2.height, D2.height) 

Deuxième mise en page

Il est possible d’afficher un tableau comme vous le souhaitez avec iText . Vous devez utiliser le positionnement des tables personnalisées et l’écriture personnalisée des lignes et des colonnes.

J’ai pu adapter cet exemple iText pour écrire sur plusieurs pages horizontalement et verticalement. L’idée est de se souvenir des lignes de début et de fin qui apparaissent verticalement sur une page. J’ai mis tout le code pour pouvoir le lancer facilement.

 public class Main { public static final Ssortingng RESULT = "results/part1/chapter04/zhang.pdf"; public static final float PAGE_HEIGHT = PageSize.A4.getHeight() - 100f; public void createPdf(Ssortingng filename) throws IOException, DocumentException { // step 1 Document document = new Document(); // step 2 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename)); // step 3 document.open(); //setup of the table: first row is a really tall one PdfPTable table = new PdfPTable(new float[] {1, 5, 5, 1}); SsortingngBuilder sb = new SsortingngBuilder(); for(int i = 0; i < 50; i++) { sb.append("tall text").append(i + 1).append("\n"); } for(int i = 0; i < 4; i++) { table.addCell(sb.toString()); } for (int i = 0; i < 50; i++) { sb = new StringBuilder("some text"); table.addCell(sb.append(i + 1).append(" col1").toString()); sb = new StringBuilder("some text"); table.addCell(sb.append(i + 1).append(" col2").toString()); sb = new StringBuilder("some text"); table.addCell(sb.append(i + 1).append(" col3").toString()); sb = new StringBuilder("some text"); table.addCell(sb.append(i + 1).append(" col4").toString()); } // set the total width of the table table.setTotalWidth(600); PdfContentByte canvas = writer.getDirectContent(); ArrayList rows = table.getRows(); //check every row height and split it if is taller than the page height //can be enhanced to split if the row is 2,3, ... n times higher than the page for (int i = 0; i < rows.size(); i++) { PdfPRow currentRow = rows.get(i); float rowHeight = currentRow.getMaxHeights(); if(rowHeight > PAGE_HEIGHT) { PdfPRow newRow = currentRow.splitRow(table,i, PAGE_HEIGHT); if(newRow != null) { rows.add(++i, newRow); } } } List chunks = new ArrayList(); int startRow = 0; int endRow = 0; float chunkHeight = 0; //determine how many rows gets in one page vertically //and remember the first and last row that gets in one page for (int i = 0; i < rows.size(); i++) { PdfPRow currentRow = rows.get(i); chunkHeight += currentRow.getMaxHeights(); endRow = i; //verify against some desired height if (chunkHeight > PAGE_HEIGHT) { //remember start and end row chunks.add(new Integer[]{startRow, endRow}); startRow = endRow; chunkHeight = 0; i--; } } //last pair chunks.add(new Integer[]{startRow, endRow + 1}); //render each pair of startRow - endRow on 2 pages horizontally, get to the next page for the next pair for(Integer[] chunk : chunks) { table.writeSelectedRows(0, 2, chunk[0], chunk[1], 236, 806, canvas); document.newPage(); table.writeSelectedRows(2, -1, chunk[0], chunk[1], 36, 806, canvas); document.newPage(); } document.close(); } public static void main(Ssortingng[] args) throws IOException, DocumentException { new Main().createPdf(RESULT); } } 

Je comprends que iText est peut-être un niveau trop bas pour les rapports, mais il peut être utilisé à côté des outils de reporting standard pour des besoins spéciaux comme celui-ci.

Mise à jour: Maintenant, les lignes plus hautes que la hauteur de la page sont divisées pour la première fois. Le code ne fait pas de division si la ligne est 2, 3, …, n fois plus grande mais peut être adaptée pour cela aussi.

Même idée ici que Dev Blanked mais en utilisant wkhtmltopdf ( https://code.google.com/p/wkhtmltopdf/ ) et certains javascript, vous pouvez obtenir ce dont vous avez besoin. Lorsque vous exécutez wkhtmltopdf contre ce violon, vous obtenez le résultat ci-dessous (capture d’écran des pages pdf). Vous pouvez placer la classe “break-after” n’importe où sur la ligne d’en-tête. Nous utilisons wkhtmltopdf côté serveur dans une application Web Java EE pour produire des rapports dynamics et les performances sont en fait très bonnes.

HTML

  
Header 1Header 2Header 3Header 4
A1
text
text
B1
text
C1 D1
A2 B2
text
text
text
C2 D2
text

Scénario

 $(document).ready(function() { var thisTable = $('#table'), otherTable= thisTable.clone(false, true), breakAfterIndex = $('tr th', thisTable).index($('tr th.break-after', thisTable)), wrapper = $('
'); wrapper.css({'page-break-before': 'always'}); wrapper.append(otherTable); thisTable.after(wrapper); $('tr', thisTable).find('th:gt(' + breakAfterIndex + ')').remove(); $('tr', thisTable).find('td:gt(' + breakAfterIndex + ')').remove(); $('tr', otherTable).find('th:lt(' + (breakAfterIndex + 1) + ')').remove(); $('tr', otherTable).find('td:lt(' + (breakAfterIndex + 1) + ')').remove(); $('tr', table).each(function(index) { var $this =$(this), $otherTr = $($('tr', otherTable).get(index)), maxHeight = Math.max($this.height(), $otherTr.height()); $this.height(maxHeight); $otherTr.height(maxHeight); }); });

Capture d'écran du PDF résultant

Avez-vous essayé http://code.google.com/p/flying-saucer/ . Il est censé convertir le HTML en PDF.

Mon conseil est d’utiliser un transformateur FOP.

Ici vous pouvez voir quelques exemples et comment l’utiliser.

Vous pouvez trouver ici quelques exemples avec fop et tables.

Jasper n’a aucun support.

Selon la documentation de Jasper, elle prend en charge, via:

  • élément break de colonne (c.-à-d. un élément break avec un atsortingbut type = column). Cela peut être placé à n’importe quel endroit dans un rapport.
  • Atsortingbut isStartNewColumn sur les groupes / en-têtes

Voir http://books.google.com.au/books?id=LWTbssKt6MUC&pg=PA165&lpg=PA165&dq=jasper+reports+%22column+break%22&source=bl&ots=aSKZfqgHR5&sig=KlH4_OiLP-cNsBPGJ7yzWPYgH_k&hl=fr&sa=X&ei=h_1kUb6YO6uhiAeNk4GYCw&redir_esc=y#v = onepage & q = colonne% 20break & f = false

Si vous êtes vraiment coincé, vous pouvez utiliser en dernier recours Excel / OpenOffice Calc: copier manuellement les données dans des cellules, les formater manuellement comme vous le souhaitez, enregistrer au format xls. Utilisez ensuite les POI apache de Java pour remplir / remplacer dynamicment les données souhaitées et les imprimer dans un fichier / PDF. Au moins, cela donne un contrôle très fin du formatage des colonnes et des lignes / des ruptures / marges, etc.