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

Struts 1 Java Discussion :

ouvrir pdf dans popup et déclencher l'impression de celui-ci


Sujet :

Struts 1 Java

  1. #1
    Membre actif Avatar de CaptainCyd
    Inscrit en
    Avril 2007
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Avril 2007
    Messages : 201
    Points : 232
    Points
    232
    Par défaut ouvrir pdf dans popup et déclencher l'impression de celui-ci


    alors, via mon appli web, je génère des documents pdf.

    Une fois ces documents pdf générer, j'ai 2 possibilités offertes à l'utilisateur:
    - juste générer le document et l'afficher dans une popup
    - générer, afficher dans une popup et déclencher l'impression de celle-ci.

    La génération des pdf se fait via une action ajax.
    Ajax appelle mon action qui une fois la génération terminée, renvoie via un flux xml, les liens sur les fichiers pdf.
    Ensuite, via une fonction javascript, je passe en paramètre l'url pour qu'elle l'ouvre dans une popup.

    ceci fonctionne très bien tant que je ne veux pas déclencher l'impression

    Au début, j'avais mis l'ordre d'impression dans la foncton qui ouvre la fenêtre popup.
    Mon panneau pour confirmer l'impression s'ouvre bien, mais le pb, c'est qu'il s'ouvre avant que mon pdf est fini de chargé dans la page.
    Quand je clique sur ok pur confirmer l'impression j'ai une erreur me disant que mon document à changer et que je dois recommencer l'impression.

    Pas de pb , je vais me brancher sur l'event onload.
    Je me suis inspiré de cette exemple de la faq pour charger mon pdf via struts et ensuite cablé mon event onload sur l'impression.

    Voici ce que j'ai rajouté dans mon fichier struts-config.xml :
    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
     
    <form-beans type="org.apache.struts.action.ActionFormBean">
     
            <!-- Logon form bean -->
    		<form-bean name="popupBean" type="drdict.struts.bean.PopupBean" />
    	</form-beans>
    <action-mappings>
    <action
                path="/popupPdf"
                type="drdict.struts.action.PopupAction"
                name="popupBean"
    			parameter="reqCode"
                scope="session"
                validate="false"
                attribute="popupBean">
                <forward name="popup" path="page.popup" />
            </action>
    </action-mappings>
    mon tiles-config.xml :
    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
     
    <?xml version="1.0" encoding="UTF-8"?>
    <tiles-definitions>
     
    	<!-- Definition de base à utiliser -->
        <definition name="base" path="/templates/base.jsp">	        
            <put name="enpied"  value="enpied.jsp"/>	      
            <put name="menu"  value="menu.jsp"/>
    		<put name="entete" value="entete.jsp"/>	 
    	</definition>
     
    <!-- Définition de la page popup -->
    	<definition name="page.popup" extends="base" >
    		<put name="body" value="/vues/popupPdf.jsp" />
    	</definition>
    </tiles-definitions>
    popupPdf.jsp :
    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
     
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="struts-bean" prefix="bean" %>
    <%@ taglib uri="struts-html" prefix="html" %>
    <%@ taglib uri="struts-layout" prefix="layout" %>
     
    <script language="javascript" type="text/javascript">
    	function imprimePdf()
    	{
    		alert('imprimePdf');
    		var imprim = dojo.byId("popupImprimer");
    		if(parseInt(imprim.value,10) == 1) 
    			window.print();
    	}
     
        dojo.addOnLoad(imprimePdf);
     
        alert('imprimePdf');
    </script>
     
    <layout:text property="popupImprimer" styleId="popupImprimer" mode="H,H,H"/>
    mon fichier PopupBean.java :
    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
     
    package drdict.struts.bean;
     
    import javax.servlet.http.HttpServletRequest;
     
    import org.apache.struts.action.ActionErrors;
    import org.apache.struts.action.ActionMapping;
     
     
    import fr.improve.struts.taglib.layout.util.DefaultForm;
     
    public class PopupBean extends DefaultForm {
     
    	/**
             * 
             */
    	private static final long serialVersionUID = 7904681008170839992L;
    	private String popupImprimer;
     
    	public PopupBean()
        {
        }
     
    	public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
     
    		//	 gestion des erreurs
    		ActionErrors erreurs = new ActionErrors();
     
    		//	 on rend la liste d'erreurs
    		return erreurs;
    	}
     
    	public String getPopupImprimer() {
    		return popupImprimer;
    	}
     
    	public void setPopupImprimer(String popupImprimer) {
    		this.popupImprimer = popupImprimer;
    	}
     
    }
    et mon fichier PopupAction.java :
    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
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
     
    package drdict.struts.action;
     
    import java.util.*;
    import java.io.*;
    import java.nio.channels.*;
     
    import javax.servlet.http.*;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts.action.*;
    import org.apache.struts.actions.*;
    import org.apache.struts.util.MessageResources;
     
    import drdict.ejb.interfaces.*;
    import drdict.ejb.entity.*;
    import drdict.struts.bean.PopupBean;
    import drdict.util.*;
     
     
    public class PopupAction extends DispatchAction {
     
    	private UtilisateurInterface uI = null;
    	private Locator locator = new Locator();
    	private static MessageResources messages = MessageResources.getMessageResources("drdict");
    	public static String localPath = messages.getMessage("files.local.root");
     
    	public PopupAction()
    	{
    	}
     
    	public ActionForward unspecified(ActionMapping mapping, ActionForm form, 
    								 HttpServletRequest request, HttpServletResponse response) 
    						throws ServletException
    	{  
    		return mapping.findForward("popup");
    	}
     
    	public ActionForward affichePdf(ActionMapping mapping, ActionForm form, 
    			 HttpServletRequest request, HttpServletResponse response) 
    	throws ServletException
    	{
    		// init des variables
    		PopupBean pb = (PopupBean)form;
     
    		// dit à la page s'il faut imprimer
    		if(request.getParameter("imprim").equals("1"))
    			pb.setPopupImprimer("1");
    		else
    			pb.setPopupImprimer("0");
     
    		// recupère le fichier pdf à ouvrir
    		String sFic = localPath + request.getParameter("fichier");
    		FileInputStream file = null;
    		ByteArrayOutputStream bos = null;
    		FileChannel src = null;
    		OutputStream os = null;
     
    		try
    		{
    			// init du flux d'entrer
    			file = new FileInputStream(sFic);
    			src = file.getChannel();
    			bos = new ByteArrayOutputStream((int)src.size());
    			byte[] tab = new byte [(int)src.size()]; 
     
    			// copi du pdf dans le tableau de byte
    			file.read(tab);
    			bos.write(tab);
     
    			// recupère les entetes et le corps
    			List<ByteArrayOutputStream> list = this.EnteteVersByte();
     
    			// Remplir ici votre bos avec le flux du PDF 
    			response.setContentType("text/html, application/pdf");
    			response.setContentLength(bos.size() + list.get(0).size() + list.get(1).size());
    			// response.setContentLength(bos.size() + list.get(0).size() + list.get(1).size());
     
    			// obtiens le flux de sortie
    			os = response.getOutputStream();
     
    			// ecrit le pdf
    			os.write(bos.toByteArray(), 0, bos.size());
     
    			// ecrit l'entete
    			os.write(list.get(0).toByteArray(), 0, list.get(0).size());
    			os.write(list.get(1).toByteArray(), 0, list.get(1).size());
     
    			// force le cache à se vider
    			os.flush();
     
    			// fermeture des flux
    			os.close();
    			bos.close();
    			src.close();
    			file.close();	
    		}
    		catch(Exception ex)
    		{
    			ex.printStackTrace();
    		}
     
    		return null;
    	}
     
    	private List<ByteArrayOutputStream> EnteteVersByte()
    	{
    		// init des variables
    		String sVal = "";
    		List<ByteArrayOutputStream> list = new ArrayList<ByteArrayOutputStream>();
    		FileChannel src = null;
     
    		String sEntete = this.getServlet().getServletContext().getRealPath("/templates/entete.jsp");
    		FileInputStream entete = null;
    		ByteArrayOutputStream bosEntete = null;
     
    		String sCorps = this.getServlet().getServletContext().getRealPath("/vues/popupPdf.jsp");
    		FileInputStream corps = null;
    		ByteArrayOutputStream bosCorps = null;
     
    		try
    		{
    			entete = new FileInputStream(sEntete);
    			src = entete.getChannel();
    			byte [] tab1 = new byte[(int)src.size()];
    			bosEntete = new ByteArrayOutputStream((int)src.size());
    			entete.read(tab1);
    			bosEntete.write(tab1);
    			list.add(bosEntete);
    			src.close();
     
    			corps = new FileInputStream(sCorps);
    			src = corps.getChannel();
    			byte [] tab2 = new byte[(int)src.size()];
    			bosCorps = new ByteArrayOutputStream((int)src.size());
    			corps.read(tab2);
    			bosCorps.write(tab2);
    			list.add(bosCorps);
    			src.close();
     
    			// ferme les flux
    			entete.close();
    			corps.close();
    		}
    		catch(Exception ex)
    		{
    			ex.printStackTrace();
    		}
     
     
    		// renvoie le resultat
    		return list;
    	}
    }
    Etant donné que j'écris directement dans le flux de sortie en mode binaire et que je ne peux pas faire un mapping.findForward sur le return, j'ai rajouté dans l'ecriture du flux le contenu de mon fichier entete.jsp et mon fichier popupPdf.jsp

    Cela donne en résultat que mon fichier pdf s'ouvre dans une popup, pas de pb.
    Que mon code contenu dans entete.jsp et popupPdf.jsp sont bien présent aussi,
    Mais le pb est que le code source ajouter par entete.jsp et popupPdf.jsp n'est pas interprété, donc ne déclenche pas l'impression

    Est-ce que qq aurait une idée de comment faire ?
    Ou si je suis sur la bonne piste, qu'est-ce qui cloche dans mon code ?

    Merci d'avance
    Il y a de jeunes pilotes audacieux, il y a de vieux pilotes, mais il n'y a pas de vieux pilotes audacieux


  2. #2
    Membre actif Avatar de CaptainCyd
    Inscrit en
    Avril 2007
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Avril 2007
    Messages : 201
    Points : 232
    Points
    232
    Par défaut
    Hello tout le monde

    j'ai l'impression que ma question en a refroidie plus d'1

    Donc, pour ne pas rester bloqué sur un pb (j'ai horreur de rester sur un échec ), j'ai farfouiller un moment et j'ai trouvé 2 solutions (non mais, ce n'est pas une machine qui avoir le dernier mot )

    Après maintes recherches sur différents sites et forums, j'en suis arrivé à la conclusion qu'il n'est pas possible de mélanger 2 types d'infos dans une page html : pdf et le reste.
    En effet, si la page est spécifié en tant que doc pdf et que c'est qu'elle rencontre en premier dans la page, le reste du code html / javascript est purement ignoré.
    Et si on fait le contraire, c'est le document pdf qui n'est pas interprété en tant que pdf mais en texte

    Donc, voici les 2 solutions que j'ai trouvé pour contourner le pb.
    (Pour le moment j'en ai expérimenter qu'une seul) :
    modifier le document pdf avec acrobat pour ajouter un action javascript pour qu'à la fin du chargement de celui, il déclenche l'impression
    générer mes docs pdf, les transformer en jpeg et afficher celle-ci.

    n'ayant pas encore acrobat, je n'ai pas pu la tester et j'ai mis en place l'autre solution

    Première chose à faire, trouvé un outil qui me permette de transformer du pdf en jpeg..
    J'ai opter pour ghostscript qui est gratuit et qui fonctionne en mode batch.
    Voici la ligne de commande à passer à ghostscript pour qu'il convertisse mon pdf en jpeg :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    C:/Program Files/gs/gs8.53/bin/gswin32.exe -dNOPAUSE -r150 -dBATCH -sDEVICE=jpeg -dJPEGQ=90 -dQFactor=1 -sPAPERSIZE=a4 -sOutputFile="{0}_%01d.jpg" "{1}.pdf"
    {0} et {1] sont à remplacer par le nom du fichier sans extension.

    Au moment je crée mes pdf, j'exécute la commande ghoscript qui permet de transformer mes pdf en jpeg via ce code java :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    try {
       String sCmd = messages.getMessage("ghostscript",dest, dest);
       Process proc = Runtime.getRuntime().exec(sCmd);
       proc.waitFor();
    } catch (IOException e) {
       e.printStackTrace(); 
    }
       catch(InterruptedException ei)
    {
       ei.printStackTrace();
    }

    J'ai gardé mes classes PopupBean et PopupAction et j'ai modifié le fichier popupPdf.jsp comme suit :
    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
     
    <%@ page language="java" contentType="application/pdf; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib uri="struts-bean" prefix="bean" %>
    <%@ taglib uri="struts-logic" prefix="logic" %>
    <%@ taglib uri="struts-html" prefix="html" %>
    <%@ taglib uri="struts-layout" prefix="layout" %>
     
    <script language="javascript" type="text/javascript">
     
     function imprimer()
     {
     	var myParam = getQueryStringByName("imprim");
     	if(myParam == "1")
     	{
     		window.print();
     		window.close();
     	}
     }
     
    dojo.addOnLoad(imprimer);
     
     
    </script>
    <layout:form action="/popupPdf" reqCode="imprimePdf" method="post">
    	<logic:iterate name="listeUrl" id="idUrl">
    		<img src="<%=idUrl%>" border="1" width="100%" height="100%" alt="">
    	</logic:iterate>
    </layout:form>
    Une fois que mes pdf et jpeg sont, généré, j'ouvre une fenêtre popup qui contient des tags img pour afficher mes images.
    et vu que je peux mélanger image, html et javascript, je peux me câbler sur l'event onload de la page pour déclencher l'impression

    inconvénient :
    - je fais 2 traitements au lieu d'1 : pdf puis jpeg
    - l'image n'a la pas même dimension à l'impression que le pdf en A4

    avantage :
    - le document met moins de tps à charger les jpeg car il n'a pas à lancer le module acrobat reader pour afficher le doc
    - il n'est pas nécessaire d'avoir acrobat reader sur la machine
    - je peux faire du javascript

    voilou, ca marche, cela résoud mon pb
    Mais quand j'aurai acrobat pour la modif direct dans le doc, je vais voir ce que cela donne je mettrai à jour ce post

    @+
    Il y a de jeunes pilotes audacieux, il y a de vieux pilotes, mais il n'y a pas de vieux pilotes audacieux


  3. #3
    Membre actif Avatar de CaptainCyd
    Inscrit en
    Avril 2007
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Avril 2007
    Messages : 201
    Points : 232
    Points
    232
    Par défaut


    Comme promis, voici le résultat de mes tests avec acrobat 5.

    Donc, avec Acrobat 5 et supérieur, il est possible de définir des actions javascript sur le document pdf, et notamment après son chargement.

    Dans mon, cas, j'utilise le même template pdf pour soit :
    - générer uniquement le document
    - générer et déclencher l'impression

    Pour pouvoir gérer le fait que le pdf doit executer l'impression de lui même, j'ai rajouté un champ texte invisible dans le document qui prend 0 comme valeur par défaut et qui a pour nom : "IMPRESSION"

    Dans mon appli java, au moment où je crée mon doc pdf à partir du template, je sais si je dois l'imprimer ou pas. Si je dois l'imprimer, je mets le champ "IMPRESSION" à 1.

    Ensuite, on niveau du template pdf, je défini l'action javascript sur le onload de celui-ci avec acrobat 5 :
    Document\définir une action liée\
    Je sélectionne Ouverture de la page
    puis j'ajoute l'action javascript qui m'interesse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if(this.getField("IMPRESSION").value == "1")
    {
       this.print(); // permet de déclencher l'impression du doc
       this.closeDoc(); // ferme le doc après l'impression 
    }
    Et voilou

    Et pour afficher le document, il suffit de balancer l'url qui pointe sur le fichier pdf, et celui-ci se débrouille comme un grand

    Donc, l'avantage a utilisé le doc pdf direct, cela evite de mettre ne place une rustine pour générer le doc pdf en jpeg et l'afficher

    Pour ma part, je pense que les 2 soluces se valent, ensuite cela dépend du contexte dans lequel on évolue
    Il y a de jeunes pilotes audacieux, il y a de vieux pilotes, mais il n'y a pas de vieux pilotes audacieux


  4. #4
    Membre actif
    Profil pro
    Developpeur
    Inscrit en
    Avril 2004
    Messages
    160
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Avril 2004
    Messages : 160
    Points : 212
    Points
    212
    Par défaut
    Qu'est ce que tu voulais dire par "template pdf"?
    Il faut préparer en avance un template, il contient quoi comme info?

    Merci.

  5. #5
    Membre actif Avatar de CaptainCyd
    Inscrit en
    Avril 2007
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Avril 2007
    Messages : 201
    Points : 232
    Points
    232
    Par défaut
    dans mon cas, j'ai un formulaire pdf qui contient des champ vide.

    Lors de mon traitement, j'ouvre ce formulaire, je remplie les champs vides et je le sauvegarde dans un nouveau pdf.
    Ce qui fait que ce formulaire vide, je l'appelle un template, car il me sert de base pour créer mon doc pdf finale.

    Mon doc pdf créé, suite à mon traitement, récupère tous les paramètres de mon template, dont le paramétrage avec le javascript sur le onload du doc.

    Maintenant, si ta question est comment faire en créant un doc pdf sans avoir un template comme dans mon cas, je ne sais pas.

    Pour modifier et sauvegarder mon formulaire, j'utilise iText qui fournit un ensemble complet de méthodes pour triturer du pdf dans tout les sens, donc il doit y avoir une fonction permettant de fixer des traitements javascript sur des event du doc pdf.
    Je n'ai pas cherché comment faire cela avec iText car j'ai Acrobat 5, et c'est plus simple de le faire avec

    voilou, j'espère avoir répondu à ta question
    Il y a de jeunes pilotes audacieux, il y a de vieux pilotes, mais il n'y a pas de vieux pilotes audacieux


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

Discussions similaires

  1. Affichage pdf dans popup + scroll ipad
    Par jameson dans le forum jQuery
    Réponses: 0
    Dernier message: 12/05/2014, 16h02
  2. Ouvrir un PDF dans une popup
    Par baggie dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 10/01/2011, 14h13
  3. Ouvrir un pdf dans une "fausse" popup
    Par nicolas2603 dans le forum jQuery
    Réponses: 20
    Dernier message: 01/09/2009, 15h32
  4. Ouvrir pdf dans VB
    Par GodGives dans le forum VB 6 et antérieur
    Réponses: 28
    Dernier message: 19/02/2008, 13h30
  5. [PDF] Ouvrir PDF dans l'explorateur par lien
    Par adrianclowes dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 17/11/2007, 17h48

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