IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

BIRT Discussion :

[Birt 4.3][Runtime] Page break en java dans une grid


Sujet :

BIRT

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 6
    Points : 4
    Points
    4
    Par défaut [Birt 4.3][Runtime] Page break en java dans une grid
    Bonjour à tous,

    Dans le cadre d'un stage, cela fait maintenant plus d'un mois que je développe un module statistiques en Java, en utilisant Birt pour générer des fichiers pdf contenant des graphes.
    J'ai donc largement eu le temps d'éplucher ce forum (merci !), ainsi que Birt-Exchange community, et beaucoup de blogs ou autres joyeusetés sur Google.

    Problème :
    Je n'arrive toujours pas à implémenter un simple saut de page dans ma Master Page (grid).

    Je me prends un NullPointer exception lorsque je fais : grid.getStyle().setPageBreakAfter("PAGE_BREAK_ALWAYS");
    J'ai aussi tenté le PageBreakInside et Before, avec tous les arguments possibles. J'ai tenté le PageBreak sur une cellule, sur une row. Bref, j'ai essayé beaucoup de choses.

    Etat actuel :
    J'ai un rapport contenant une Master Page avec une grid, un header et un footer. Dans les cellules de ma grid, j'ai des objets TextItemHandle et ImageHandle.

    Les images et le texte s'ajoutent dynamiquement, en fonction des paramètres fournis par mon IHM. Donc si j'en ai envie, je suis capable de générer un rapport contenant 50 graphiques + 50 zones de texte.
    Pour le moment, lorsque j'ajoute des graphes, ceux-ci se mettent à l'échelle automatiquement. Donc si je mets 2 graphes, je les vois correctement. Mais si j'en mets 50, je verrai 50 graphes microscopiques tenant sur une seule page A4 pdf.

    Objectif :
    J'aimerais effectuer un saut de page automatique tous les deux graphes, à l'intérieur de ma grid.
    C'est-à-dire que chaque page pdf doit contenir 2 graphes maximum + 1 footer + 1 header.
    Exemple : si j'ajoute 40 graphiques, je dois avoir 20 pages contenant chacune 2 graphiques (+ 1 page contenant le titre).

    Mon code :
    Voici à quoi ressemble mon code qui génère mon objet ReportDesignHandle. Le PageBreak se trouve tout à la fin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    public ReportDesignHandle createReportDesignHandle() {
     
    		// Configure the Engine and start the Platform
    		DesignConfig config = new DesignConfig();
     
    		IDesignEngine engine = null;
     
    		Platform.startup(config);
    		IDesignEngineFactory factory = (IDesignEngineFactory) Platform.createFactoryObject(IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY);
    		engine = factory.createDesignEngine(config);
     
    		SessionHandle session = engine.newSessionHandle(ULocale.ENGLISH);
     
    		// Create a new report design.
    		ReportDesignHandle design = session.createDesign();
     
    		// The element factory creates instances of the various BIRT elements.
    		ElementFactory efactory = design.getElementFactory();
     
    		// Create a simple master page that describes how the report will appear when printed.
    		// Note: The report will fail to load in the BIRT designer unless you create a master page.
    		SimpleMasterPageHandle element = efactory.newSimpleMasterPage("Page Master");
     
    		/* +-------------------------------------------------+ */
    		/* |             -- HEADER/FOOTER --                 | */
    		/* +-------------------------------------------------+ */
     
    		// ---------------------------- Header (Grid) ---------------------------- //
    		GridHandle headerGrid = efactory.newGridItem("HeaderGrid", 2 /* cols */, 1 /* row */);
    		headerGrid.setWidth("100%");
     
    		// HEADER CELL n°1 //
    		RowHandle headerRow = (RowHandle) headerGrid.getRows().get(0);
    		CellHandle headerCellZero = (CellHandle) headerRow.getCells().get(0);
     
    		ImageHandle imageHeader = efactory.newImage(null);
    		imageHeader.setFile("\"" + InputPath + "image_header.png" + "\"");
    		imageHeader.setWidth("20%");
    		imageHeader.setHeight("20%");
    		headerCellZero.getContent().add(imageHeader);
     
    		// HEADER CELL n°2 //
    		headerRow = (RowHandle) headerGrid.getRows().get(0);
    		CellHandle headerCellOne = (CellHandle) headerRow.getCells().get(1);
     
    		TextItemHandle textHeader = efactory.newTextItem(null);
    		textHeader.setContentType(DesignChoiceConstants.TEXT_CONTENT_TYPE_HTML);
    		textHeader.setContent("Header text here");
    		headerCellOne.getContent().add(textHeader);
     
    		// ---------------------------- Footer (Text) ---------------------------- //
    		DesignElementHandle footerText = efactory.newTextItem("footer");
     
    		footerText.setProperty("contentType", "html");
    		String footer = "<p align="+"center"+">" + "Page "+currentPage+" of "+totalPage+ "</p>";
    		footerText.setStringProperty("content", footer);
     
    		// ------------------------ Adding Footer/Header ------------------------ //
    		element.getPageFooter().add(footerText);
    		element.getPageHeader().add(headerGrid);
    		design.getMasterPages().add(element);
     
    		/* +-------------------------------------------------+ */
    		/* |                 -- BODY --                      | */
    		/* +-------------------------------------------------+ */
     
    		// Create a grid and add it to the "body" slot of the report design.
    		GridHandle grid = efactory.newGridItem("MainGrid", 1 /* cols */, (1 + 2 * this.charts.size()) /* row */);
    		grid.setWidth("100%");
     
    		design.getBody().add(grid);
     
    			/* +-------------------------------------------------+ */
    			/* |                -- ROW 0 --                      | */
    			/* +-------------------------------------------------+ */
    			RowHandle row = (RowHandle) grid.getRows().get(0);
    			CellHandle cell = (CellHandle) row.getCells().get(0);
     
    			// Title of Document
    			TextItemHandle textTitle = efactory.newTextItem(null);
    			textTitle.setContentType(DesignChoiceConstants.TEXT_CONTENT_TYPE_HTML);
    			textTitle.setContent("<p align="+"center"+" style="+"font-size:25px"+">"+"<b>"+ titleOfDocument + "</b><br></p>");
    			textTitle.setWidth("100%");
    			cell.getContent().add(textTitle);
     
     
    			/* +-------------------------------------------------+ */
    			/* |           -- from ROW 1 to ROW_final --         | */
    			/* +-------------------------------------------------+ */
     
    			for (int i = 0; i < this.charts.size(); i++) {
     
    				// Title of Image
    				row = (RowHandle) grid.getRows().get(1 + 2 * i);
    				CellHandle cellImage = (CellHandle) row.getCells().get(0);
     
    				TextItemHandle textImage = efactory.newTextItem(null);
    				textImage.setContentType(DesignChoiceConstants.TEXT_CONTENT_TYPE_HTML);
    				textImage.setContent("<p align=" + "left" + ">" + titleOfImage(i) + "</p>");
    				textImage.setWidth("100%");
    				cellImage.getContent().add(textImage);
     
    				// Image
    				row = (RowHandle) grid.getRows().get(2 + 2 * i);
    				cellImage = (CellHandle) row.getCells().get(0);
     
    				ImageHandle image = efactory.newImage(null);
    				image.setFile("\"" + InputPath + "image_" + i + ".png" + "\"");
    				image.setWidth("50%");
    				image.setHeight("50%");
    				cellImage.getContent().add(image);
     
    				// ---------------------- Page Break ----------------------------- //
    				if (i%2 == 0)
    					grid.getStyle().setPageBreakAfter("PAGE_BREAK_ALWAYS");
    			}
     
    		return design;
    	}

  2. #2
    Membre éclairé
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2009
    Messages
    529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2009
    Messages : 529
    Points : 836
    Points
    836
    Par défaut
    Salut,

    PAGE_BREAK_ALWAYS n'est pas la valeur d'une constante mais son nom, à l'intérieur de la classe DesignChoiceConstants.

    Tu peux aussi directement utiliser la valeur. Par exemple ce code fonctionne dans le designer Eclipse, qu'on l'applique sur un élément Grid ou une de ses lignes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.getStyle().setPageBreakAfter("always");

  3. #3
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Salut,

    Je te remercie pour ta réponse donino
    Malheureusement, j'avais déjà testé cette ligne de code et ça ne marchait pas.

    Du coup, suite à ton post, je viens de la retester à différents emplacements, avec différents objets (row, design, grid, cell), mais rien à faire... J'ai toujours un NullPointerException.

    J'ai l'impression que le getStyle() est vide. Est-ce que ça signifie pour réaliser les sauts de page, il faut créer spécifiquement un objet SharedStyleHandle, puis le passer à notre objet, un peu comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SharedStyleHandle style = new SharedStyleHandle(null, null);
    row.setStyle(style);
    row.getStyle().setPageBreakAfter("always");
    Parce que ça non plus, ça ne marche pas :s

  4. #4
    Membre éclairé
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2009
    Messages
    529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2009
    Messages : 529
    Points : 836
    Points
    836
    Par défaut
    Non pas la peine de créer l'objet de style, l'élément Grid s'en charge. Es-tu certain à 100% que le NullException vient de cette ligne? Par exemple on crée (1+2*size) lignes dans la grille, mais on accéde à la ligne (2+2*size) pour insérer l'image, ce qui renvoie éventuellement null à la dernière itération et fait logiquement planter la suite.

    Rajoute un test de valeur null sur l'objet RowHandle avec des messages de log, ou encore mieux une execution pas à pas et le problème ne devrait pas y résister longtemps

    EDIT:Ah dsl je me suis emmélé les pinceaux entre les "i" et les "chart.size()" Mais bon la remarque reste valable je pense que le pb se situe plutôt sur une ligne à null que sur le getStyle()

  5. #5
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Je te remercie de nouveau pour tes réponses. C'est gentil de prendre sur ton temps pour me filer un coup de main !

    Alors :

    1) Oui, je suis sûr à 1000% que le problème vient du getStyle(). Lorsque je commente la ligne, je génère mon rapport.pdf sans aucun souci.

    2) Histoire de lever le doute, j'ai quand même fait le bourrin en augmentant brutalement la taille de ma grid :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GridHandle grid = efactory.newGridItem("MainGrid", 1 /* cols */, (500 + 2 * this.charts.size()) /* row */);
    (je génère toujours mon rapport.pdf sans problème dans ces conditions)

    3) J'ai ajouté des tests + "printf" pour confirmer que le souci vient bien du getStyle() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    if (row != null) {
    	System.out.println("row n'est pas null !");
    	if (row.getStyle() == null) {
    		System.out.println("mais row.getStyle() est null !");
    	} else {
                    grid.getStyle().setPageBreakAfter("always");
    	}
    }

    Lorsque je lance mon programme, j'ai donc ceci qui s'affiche :
    row n'est pas null !
    mais row.getStyle() est null !

    Conclusion : c'est bien le getStyle() qui m'enquiquine

  6. #6
    Membre éclairé
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2009
    Messages
    529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2009
    Messages : 529
    Points : 836
    Points
    836
    Par défaut
    Bon bah je séche dsl

    Essaie peut être de créer le style comme tu l'as fait plus haut, mais avec les arguments qui vont bien pour le lier à la ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SharedStyleHandle style = new SharedStyleHandle(row.getModule(), row.getElement());
    row.setStyle(style);
    row.getStyle().setPageBreakAfter("always");

  7. #7
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Ta solution avait l'air bonne, mais malheureusement j'ai encore une erreur.
    Cette fois-ci c'est la ligne setStyle qui déconne :
    Le message d'erreur m'explique que :
    TableRow cannot be cast as a StyleElement
    Bizarre que ça foire à l'exécution... parce que c'est okay sous Eclipse.

    Donc j'ai encore testé plein de choses différentes sur le modèle que tu me conseilles, mais ça n'aboutit pas. Je poursuis mes recherches !

  8. #8
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Solution trouvée !

    En fait il ne fallait pas toucher au code de génération de l'objet ReportDesignHandle. Il fallait s'en prendre directement à la Run & Render task !

    Je vous poste ici le bout de code qui permet d'ajouter automatiquement des pages à votre fichier pdf pour y faire tenir proprement tout le contenu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    IRenderOption options = new RenderOption();
    options.setOutputFormat("pdf");
    options.setOutputFileName(this.pdfOutputPath + nameOfDocument + ".pdf");
     
    PDFRenderOption pdfOptions = new PDFRenderOption(options);
    pdfOptions.setOption(IPDFRenderOption.PAGE_OVERFLOW, "OUTPUT_TO_MULTIPLE_PAGES");
    pdfOptions.setOption(IPDFRenderOption.PAGEBREAK_PAGINATION_ONLY, Boolean.FALSE);
    Dernière question : Comment mettre en place une pagination automatique ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. importer une classe java dans une page jsp
    Par chafik_si3 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 26/03/2009, 15h51
  2. [debutant] Comment mettre du Java dans une page HTML
    Par SPACHFR dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 10/12/2008, 23h48
  3. comment appeler une classe java dans une page jsp?
    Par limalima dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 21/11/2008, 22h59
  4. détection d'applet java dans une page HTML
    Par karimaensi dans le forum Applets
    Réponses: 3
    Dernier message: 20/09/2006, 23h36
  5. JFrame java dans une page html
    Par atito dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 19/08/2006, 13h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo