web-dev-qa-db-fra.com

Créez un fichier Excel que les utilisateurs pourront télécharger avec Apache POI

Je suis capable de créer un fichier Excel avec Apache Poi. Cependant, je veux que les utilisateurs puissent télécharger ceci en tant que "vrai" fichier Excel. l'effet que je veux obtenir serait d'avoir une boîte de dialogue permettant à l'utilisateur de télécharger le fichier. c'est similaire à l'utilisation 

<%@ page contentType="application/vnd.ms-Excel" pageEncoding="ISO-8859-1"%> 
<%response.setHeader("Content-Disposition", "attachment;filename=myfile.xls"); %>

avec une exception critique: je dois permettre à l'utilisateur de télécharger un fichier Excel approprié. J'ai lu quelque part que le code ci-dessus indique simplement au client que le serveur envoie un fichier Excel

16
user571099

Effectuez le travail dans une servlet normale au lieu d'un fichier JSP. Un fichier JSP est conçu pour générer dynamiquement du code HTML et utilise un rédacteur de caractères pour cela au lieu d'un flux de sortie binaire et ne corromprait donc que votre fichier Excel généré par POI, qui est essentiellement un flux binaire.

Donc, en gros, tout ce que vous devez faire dans la méthode doGet() de la servlet est le suivant:

response.setContentType("application/vnd.ms-Excel");
response.setHeader("Content-Disposition", "attachment; filename=filename.xls");
HSSFWorkbook workbook = new HSSFWorkbook();
// ...
// Now populate workbook the usual way.
// ...
workbook.write(response.getOutputStream()); // Write workbook to response.
workbook.close();

Maintenant, pour le télécharger, appelez le servlet par son URL au lieu du fichier JSP.

35
BalusC

S'il est vrai qu'il est plus habituel d'écrire une pièce jointe binaire en utilisant un servlet plutôt qu'un jsp, il est certainement possible d'écrire une pièce jointe binaire à partir d'un jsp. Et l'avantage de le faire est que vous n'avez pas à vous soucier de la configuration de web.xml ou du rechargement de votre application. Cela peut être une considération importante, selon votre environnement de serveur Web.

Voici un exemple jsp qui utilise poi pour envoyer une pièce jointe binaire à un navigateur.

<%@page import="org.Apache.poi.hssf.usermodel.*" %><%@page import="Java.io.*" %><%

// create a small spreadsheet
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue("Some text");

// write it as an Excel attachment
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);
byte [] outArray = outByteStream.toByteArray();
response.setContentType("application/ms-Excel");
response.setContentLength(outArray.length);
response.setHeader("Expires:", "0"); // eliminates browser caching
response.setHeader("Content-Disposition", "attachment; filename=testxls.xls");
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();

%>

L'astuce importante consiste à s'assurer qu'il n'y a qu'une seule ligne avec toutes vos directives d'importation et autres avant le "<%" qui commence votre code. Sinon, jsp peut générer de nouvelles lignes initiales et corrompre votre sortie.

Aussi, je vous suggère de toujours définir la longueur du contenu. Certains navigateurs ne fonctionneront pas correctement s'ils ne sont pas configurés. C'est pourquoi j'ai d'abord sorti ma feuille de calcul dans un tableau d'octets, afin de pouvoir définir la longueur avant d'envoyer les données.

20
Howard Schutzman

si vous voulez télécharger don, t utilisez le classeur hssf, il ralentira et consommera plus d’espace

SXSSFWorkbook workbook = new SXSSFWorkbook(100); 
workbook.setCompressTempFiles(true);
Sheet sh = workbook.createSheet();
//write your data on sheet

//below code will download file in browser default download folder
response.setContentType("application/vnd.ms-Excel");
            response.setHeader("Content-Disposition", "attachment; filename="+filename+".xlsx");
            workbook.write(response.getOutputStream());
            workbook.close();
            workbook.dispose();

Pour Pdf, utilisez Itext

     Document document = new Document();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfWriter.getInstance(document, baos);
            document.open(); 
//write your code

 document.add("content");
            document.close();
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setContentType("application/pdf");
            response.addHeader("Content-Disposition", "attachment; filename="+filename+".pdf");
            response.setContentLength(baos.size());
            OutputStream os = response.getOutputStream();
            baos.writeTo(os);
            os.flush();
            os.close();
0
abhinavxeon