JAVA: Exporter des données (de la base de données) vers excel et les envoyer côté client


Comme le titre le suggère, je dois mettre des données (que j'ai obtenues de la base de données) dans une feuille Excel, puis les envoyer côté client afin que l'utilisateur puisse enregistrer , ouvrir ou annuler l'action.

J'ai vu quelques articles à ce sujet, le plus proche étant: Comment puis-je amener l'utilisateur à télécharger mon fichier? (Java, MVC, Excel, POI) . En me référant aux liens fournis par Stevens, j'ai essayé le code suivant:

public String execute(){
    setContentDisposition("attachment; filename=\"" + ename + "\"");
    try{
        ServletContext servletContext = ServletActionContext.getServletContext();
        String filePath = servletContext.getRealPath("/WEB-INF/template/excel/mytemplate.xls");
        File file = new File(filePath);
        Workbook wb = WorkbookFactory.create(new FileInputStream(file));
        Sheet sheet = wb.getSheetAt(0);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        wb.write(baos);
        InputStream excelStream;
        excelStream = new ByteArrayInputStream(baos.toByteArray());
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
    return SUCCESS;
}

Ici, tout d'abord WorkbookFactory n'est pas défini. Deuxièmement, je ne pouvais pas comprenez bien comment fonctionne le code.

J'ai aussi trouvé ce lien : http://www.roseindia.net/answers/viewqa/Java-Beginners/14930-How-to-export-data-from-database-to-excel-sheet-by-using-java--in-standalone-project.html. Mais ici, le fichier Excel est enregistré sur le serveur. Je veux que le fichier ne soit pas enregistré côté serveur, il devrait directement aller côté client

(si cela aide) j'utilise: struts 2 framework, hibernate

Je suis ouvert à utiliser d'autres des choses comme l'API POI, jQuery ou toute autre bonne chose.

Je ne peux pas utiliser displayTag pour une raison quelconque.

Javascript serait mon dernier recours (bien que j'ai implémenté avec lui) car il nécessite de modifier certains paramètres de sécurité par défaut du navigateur (si cela peut être évité, je suis également ouvert à javascript).

Veuillez indiquer comment dois-je procéder maintenant.

Merci!!

MODIFIER:

    <result-types>
        <result-type name="jsp" class="org.apache.struts2.views.jsp"/>
        <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
        <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
    </result-types>
    <action name="myActionName" class="package.myActionClass">
         <result type="stream">
            <param name="contentType">"application/vnd.ms-excel"</param>
            <param name="inputName">excelStream</param>
            <param name="contentDisposition">contentDisposition</param>
            <param name="bufferSize">1024</param>
         </result>
    </action>

L'erreur lors de l'exécution de l'action:

java.lang.reflect.InvocationTargetException

java.lang.IncompatibleClassChangeError: Class org.apache.poi.hssf.usermodel.HSSFWorkbook does not implement the requested interface org.apache.poi.ss.usermodel.Workbook
Author: Community, 2012-02-15

2 answers

D'accord. Donc, finalement, j'ai fini avec tous les barrages routiers et j'ai trouvé un moyen de le faire.

J'ai réalisé que le problème auquel je faisais face n'était pas dans la création du fichier Excel, le problème était de l'envoyer côté client, et cela aussi sans créer de fichier ou de fichier temporaire sur le serveur.

Voici donc comment s'y prendre (j'ai arraché des détails de mon code d'origine afin que vous puissiez facilement le comprendre).

Dans le fichier "action" vous devez d'abord créer un Objet HSSFWorkbook, mettez des données dessus, puis sans les enregistrer sur le disque sur le serveur, envoyez-les au client à l'aide d'inputstream.

Code du fichier d'action:

public String execute(){

    setContentDisposition("attachment; filename=\"" + ename + ".xls\"");

    try{
        HSSFWorkbook hwb=new HSSFWorkbook();
        HSSFSheet sheet =  hwb.createSheet("new sheet");

        //////You can repeat this part using for or while to create multiple rows//////
            HSSFRow row = sheet.createRow(rowNum);
            row.createCell(0).setValue("col0");
            row.createCell(1).setValue("col1");
            row.createCell(2).setValue("col2");
            row.createCell(3).setValue("col3");
            .
            .
            .
        ///////////////////////////////////////////////////////////////////////////////

        ///////////////////////////////////////////////////////////////////////////////
        //////Now you are ready with the HSSFworkbook object to be sent to client//////
        ///////////////////////////////////////////////////////////////////////////////

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        hwb.write(baos);
        excelStream = new ByteArrayInputStream(baos.toByteArray());

        ///////////////////////////////////////////////////////////////////////////////
        ////Here HSSFWorkbook object is sent directly to client w/o saving on server///
        ///////////////////////////////////////////////////////////////////////////////
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
    return SUCCESS;
}

Maintenant, dans le fichier struts-config, il suffit d'écrire (notez qu'excelStream & contentDisposition a été défini dans l'action elle-même, le type de résultat ici est org.apache.struts2.dispatcher.StreamResult):

    <action name="actionName" class="actionClass">
        <result type="stream">
            <param name="contentType">"application/vnd.ms-excel"</param>
            <param name="inputName">excelStream</param>
            <param name="contentDisposition">contentDisposition</param>
            <param name="bufferSize">1024</param>
        </result>
    </action>

C'est tout. Maintenant, quand l'action est exécutée, l'utilisateur sera invité à ouvrir ou enregistrer le fichier.

:)

 10
Author: kanishk, 2012-02-16 11:44:02

Vous avez deux copies différentes de POI sur votre chemin de classe, une ancienne et une nouvelle. C'est pourquoi vous obtenez l'exception java.lang.IncompatibleClassChangeError: Classe org.Apache.pi.hssf.usermodel.HSSFWorkbook n'implémente pas l'organisation d'interface demandée.Apache.pi.ss.usermodel.Classeur - vous avez compilé avec la nouvelle copie, mais au moment de l'exécution, il trouve de nouveaux et d'anciens pots.

Ceci est couvert dans la FAQ POI. Idéalement vous devriez juste pouvoir regarder tout les pots dans votre configuration,et zapper l'ancien POI. Sinon, l'entrée POI FAQ a un exemple de code que vous pouvez utiliser pour que la JVM imprime d'où elle a chargé des classes POI. Cela vous montrera le nom du fichier jar, et vous pouvez supprimer l'ancien.

 2
Author: Gagravarr, 2012-02-16 10:33:25