Solution iFrame

Fermé
TempsMort0 Messages postés 43 Date d'inscription mardi 22 janvier 2013 Statut Membre Dernière intervention 1 août 2018 - 13 juil. 2018 à 16:58
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 - 1 août 2018 à 19:42
Bonjour,

J'ai actuellement un site réalisé en jsp/servlets, je souhaite afficher un fichier Excel qui est un fichier local, il y a quelques façons de procéder d'après mes recherches, créer un .html à partir d'Excel, utiliser la méthode "incorporer" ou "sauvegarder en page web"
à partir d'Excel, d'Excel Online (Google Docs) ou encore OneDrive.

En gros, j'ai une page qui effectue des changements sur un fichier Excel, et je veux une vue du fichier Excel (non éditable) sur celle-ci, je veux que quand la page se rafraîchisse, le fichier Excel soit relu, donc une approche locale semble adaptée.

<iframe  src="https://docs.google.com/spreadsheets/d/e/2PACX-1vQAV98EZMWLm11wtZ3S12zePTex5aVRwqTSq0GX50YQEDaY5tDh1nm9sOZTL0kqKQ6C70i1HNAvAhF9/pubhtml?gid=865291893&single=true&widget=true&headers=true" </iframe>


Ce genre d'iframe marche mais lors de la réactualisation, le fichier n'est pas relu instantanément.

J'ai vu ce genre d'alternative : https://www.lije-creative.com/afficher-un-fichier-xls-dans-une-page-web/
car j'ai besoin d'avoir les repères de la grille Excel, donc je dois faire comprendre le php à Tomcat.

Auriez-vous une meilleure solution ?
Ou bien, comment puis-je faire marcher ce php, je ne m'y connais pas dans ce langage.
Faut-il le couple serveur Apache/Tomcat ?
J'ai essayé de nombreuses choses trouvées sur internet, mais il y a toujours un problème que je ne sais régler.

Merci d'avance
Corentin

1 réponse

KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié le 13 juil. 2018 à 18:04
Bonjour,

"Ce genre d'iframe marche mais lors de la réactualisation, le fichier n'est pas relu instantanément."
C'est normal, Google stocke une copie du fichier sur le cloud, il ne lit jamais ton fichier local.

"je dois faire comprendre le php à Tomcat"
Non, si tu fais du Java tu ne fais pas du PHP, ça n'a pas de sens. Tu peux faire la même chose avec une JSP (en plus long car il faut tout réécrire, ou trouver une bibliothèque, mais en Java, qui fait la même chose)

Le plus propre de lire ta feuille Excel à l'aide de Apache POI et la restituer en HTML via ta JSP.
Par exemple à l'aide de bibliothèques JavaScript comme celles proposées sur jspreadsheets.com

Un exemple avec jexcel, voici ce que tu pourrais mettre dans ta JSP.
(en remplaçant bien sûr les valeurs de
jexcelData
par tes lignes et colonnes lues avec Apache POI)

<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
        <script src="http://cdn.bossanova.uk/js/jquery.jexcel.js"></script>
        <link rel="stylesheet" href="http://cdn.bossanova.uk/css/jquery.jexcel.css" type="text/css"/>
    </head>
    <body>
        <div id="jexcelDiv"></div>
        <script>
            jexcelData = [
                ['Google', 1998, 807.80],
                ['Apple', 1976, 116.52],
                ['Yahoo', 1994, 38.66],
            ];
            $('#jexcelDiv').jexcel({ data:jexcelData, colWidths: [ 300, 80, 100 ] });
        </script>
    </body>
</html>

Ce qui donnerait ceci :
0
Merci de ta réponse,

J'ai tenté quelques fois avec Handsontable, puis j'ai essayé avec jExcel, plusieurs façons de remplir ce tableau avec les valeurs déjà récupérées dans un .java, le problème est la façon dont je m'y prend ou la façon dont je fais stocker mes List dans la session.

<%
    List<Consommable> conso = (List<Consommable>) request.getAttribute("conso");
%>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="http://cdn.bossanova.uk/js/jquery.jexcel.js"></script>
[...]
<div id="jexcelDiv" style="height: 700px; background-color: white; color: black;"></div>
                <script>
                    jexcelData = [
                        <%
                        for ( Consommable consommable : conso)
                        {
                        %>  [<%=consommable.getDesignation()%>,<%=consommable.getFournisseur()%>,
                            <%=consommable.getFabriquant()%>,<%=consommable.getReference()%>,
                            <%=consommable.getQteInventaire()%>,<%=consommable.getQteOld()%>,
                            <%=consommable.getQteOldBis()%>,<%=consommable.getPrixAchatMag()%>,
                            <%=consommable.getEntreeMag()%>,<%=consommable.getSortieMag()%>,
                            <%=consommable.getInventaireOld()%>,<%=consommable.getStockActuel()%>,
                            <%=consommable.getPrixTotalStock()%>,<%=consommable.getConditionnementAchat()%>,
                            <%=consommable.getConditionnementSortie()%>, <%=consommable.getPrixSortieHT()%>,
                            <%=consommable.getStockMinimum()%>]
                        <%}%>
                    ];
                    $('#jexcelDiv').jexcel({
                        data:jexcelData, colHeaders: ['Désignation' , 'Fournisseur', 'Fabriquant',
                            'Référence', 'Qté Inventaire', 'Qté 30_07_15', 'Qté 30_09_15', 'Prix Achat Magasin', 'Entrée Mag.',
                            'Sortie Mag', 'Inv. 14_12_15', 'Stock Actuel', 'Prix Total Stock', 'Conditionnement à l\'achat',
                            'Conditionnement des sorties', 'Prix de la sortie mag.HT valorisé', 'Valeur min. pour Réapprovisionnement'],
                        colWidths: [ 300, 80, 100 ] });
                </script>
[...]


C'est sale mais je me suis dis que c'était la façon la plus simple de voir si ça marche.

Mon ArrayList "conso" est dans le fichier CommandeStock qui n'est pas lié à ce qui nous intéresse mais est celle qui parcourt en premier le fichier Excel.
Je les stocke :
req.getSession().setAttribute("conso", conso);

req.setAttribute("conso", conso);


Je les reprends dans la Servlet (GestionStoclk) lié à ma Jsp affichant le résultat voulu :

List<Consommable> conso = (List<Consommable>) req.getSession().getAttribute("conso");
req.setAttribute("conso", conso);


Et j'ai un NullPointerException à chaque fois que j'appelle un "conso.get(0)" pour tester ou "conso.get(0).getDesignation()" et même avec ce foreach donc l'ArrayList est vide ou mal stockée dans la session.
Aurais-tu une idée ?
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015 > TempsMort0
18 juil. 2018 à 20:57
Attention à ne pas mélanger les attributs, il y a 4 scopes différents, avec chacun un ensemble d'attributs différent, donc quand tu fait un setAttribute dans un scope, il faut faire le getAttribute sur le même scope, sinon tu recevras null d'où les erreurs NullPointerException.

Pour déboguer tu peux temporairement afficher le contenu des ensembles des 4 scopes pour visualiser dans quel scope est l'attribut que tu cherches et corriger le code (soit au moment du set, soit au moment du get)

Exemple :

<hr>Débogage
    <% for (int scope = 1; scope <= 4; scope++) { %>
        <hr><li>Scope <%= scope %>
        <ul><%
            java.util.Enumeration<String> names = pageContext.getAttributeNamesInScope(scope);
            while (names.hasMoreElements()) {
                String name = names.nextElement();
                %><li><%= name %> &rarr; <%= pageContext.getAttribute(name, scope) %></li><%
            }
        %></ul>
    <%}%>
<hr>

Remarque :
0
Ok je comprends la chose après quelques heures dedans, mais je ne trouve pas ma valeur dans les scopes.
Je comprends que si je fais :

req.getSession().setAttribute("conso",conso);


"conso" est stocké dans la session et non dans la requête ni dans la page.
Il était donc logique de récupérer la valeur de cette façon :

List<Consommable> conso = (List<Consommable>) request.getSession().getAttribute("conso");


(Je stocke dans la session car la servlet avec le setter et le jsp avec le getter ne sont liés en aucun point en terme de requête) J'ai pensé que comme la servlet n'était pas appelée, une de ses fonctions qui remplie "conso" ne serait pas appelée non plus, mais je ne pense pas au final.

Je ne retrouve pas "conso" dans l'affichage des scopes, il me manque des informations que je ne trouve pas, les valeurs stockées dans les sessions comme celle-là a-t-elle besoin de voir sa servlet éxecutée afin que les valeurs soient stockées dans la session ?
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015 > TempsMort0
25 juil. 2018 à 19:46
Comme pour tout objet en Java, tu ne peux pas faire le get si tu n'as pas fait le set avant.
Donc si c'est une servlet qui gère le set, elle doit être appelée avant la servlet qui fait le get.

Éventuellement, tu peux faire une méthode qui fait le get, et quand il ne la trouve pas l'initialise.
Cette méthode pourrait alors être appelée par n'importe quelle servlet, sans problème d'ordre, la première servlet qui en a besoin l'initialise dans la session.

Exemple :

public List<Consommable> getConsommables(HttpSession session) {
    List<Consommable> conso = (List<Consommable>) session.getAttribute("conso");
    if (conso == null) {
        conso = initConsommables(); // lecture du fichier Excel par exemple
        session.setAttribute("conso", conso);
    }
    return conso;
}

List<Consommable> conso = getConsommables(request.getSession());

Remarque : si ta liste de consommables est la même pour tous les utilisateurs, tu pourrais la mettre dans le scope de l'application, plutôt que dans le scope de session de chaque utilisateur.
0
Merci bien, après cette modif et l'ajout de cette méthode utile je vois maintenant tout le contenu de conso dans le scope 3, mais l'affichage ne fonctionne pas.
L'importante chose est que toutes les valeurs sont passées, dans le code source de la page sur navigateur, toutes les valeurs sont passées dans la partie du script mais l'affichage ne se fait pas, aurai-je raté quelque chose ?

<div id="jexcelDiv" style="height: 700px; "></div>
                <script>
                    jexcelData = [
                        <%
                        assert conso != null;for ( Consommable consommable : conso)
                        {
                        %>  [<%=consommable.getDesignation()%>,<%=consommable.getFournisseur()%>,
                            <%=consommable.getFabriquant()%>,<%=consommable.getReference()%>,
                            <%=consommable.getQteInventaire()%>,<%=consommable.getQteOld()%>,
                            <%=consommable.getQteOldBis()%>,<%=consommable.getPrixAchatMag()%>,
                            <%=consommable.getEntreeMag()%>,<%=consommable.getSortieMag()%>,
                            <%=consommable.getInventaireOld()%>,<%=consommable.getStockActuel()%>,
                            <%=consommable.getPrixTotalStock()%>,<%=consommable.getConditionnementAchat()%>,
                            <%=consommable.getConditionnementSortie()%>, <%=consommable.getPrixSortieHT()%>,
                            <%=consommable.getStockMinimum()%>]
                        <%}%>
                    ];
                    $('#jexcelDiv').jexcel({
                        data:jexcelData, colHeaders: ['Désignation' , 'Fournisseur', 'Fabriquant',
                            'Référence', 'Qté Inventaire', 'Qté 30_07_15', 'Qté 30_09_15', 'Prix Achat Magasin', 'Entrée Mag.',
                            'Sortie Mag', 'Inv. 14_12_15', 'Stock Actuel', 'Prix Total Stock', 'Conditionnement à l\'achat',
                            'Conditionnement des sorties', 'Prix de la sortie mag.HT valorisé', 'Valeur min. pour Réapprovisionnement'],
                        colWidths: [ 300, 80, 100 ] });
                </script>
0