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é:
BIRT prétend supporter cela, mais l’implémentation réelle est tellement boguée qu’elle ne peut pas être utilisée. Pour une telle fonctionnalité, il va de soi que la hauteur des rangées rest constante sur toutes les pages, ce qui permet d’aligner les rangées lorsque les pages sont placées les unes à côté des autres. BIRT calcule cependant la hauteur de ligne requirejse séparément pour chaque page.
Jasper n’a aucun support.
J’ai également considéré Apache FOP, mais je ne trouve aucune syntaxe appropriée pour cela dans la spécification XSL-FO.
iText est généralement un peu trop “bas” pour cette tâche (ce qui rend difficile la mise en page d’autres parties des documents PDF prévus), mais ne semble pas offrir de support.
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.
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)
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 1 Header 2 Header 3 Header 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); }); });
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:
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.