J'ai écrit du code qui génère un fichier Excel en utilisant REST JAX-RS et j'ai confirmé que le fichier Excel généré se trouve dans le répertoire du serveur GlassFish.
Mais mon objectif est lorsque l'utilisateur clique sur le bouton (qui génère Excel .xls), je souhaite que la fenêtre de téléchargement s'affiche pour demander à l'utilisateur s'il doit enregistrer ou ouvrir le fichier .xls comme tout autre service Web pour télécharger tout type de fichiers.
Selon ma recherche, l'étape est:
générer Excel .xls (TERMINÉ)
écrire Excel pour diffuser
dans le fichier JAX-RS, définissez l'en-tête de réponse sur quelque chose comme,
String fileName = "Blah_Report.xls"; response.setHeader ("Content-Disposition", "attachment; filename =" + fileName);
Ma question est que je fais tout cela dans un fichier JAX-RS et je n'ai pas d'objet HttpServletResponse disponible.
Selon la réponse de Ajouter un en-tête de réponse au service Web JAX-RS
Il dit:
Vous pouvez injecter une référence à la HttpServletResponse réelle via l'annotation @Context dans votre webservice et utiliser addHeader () etc. pour ajouter votre en-tête.
Je ne peux pas vraiment comprendre ce que cela signifie sans exemple de code ..
Vous n'avez pas besoin de HttpServletResponse pour définir un en-tête sur la réponse. Vous pouvez le faire en utilisant javax.ws.rs.core.Response. Faites simplement votre méthode pour renvoyer Response au lieu d'entité:
return Response.ok(entity).header("Content-Disposition", "attachment; filename=\"" + fileName + "\"").build()
Si vous souhaitez toujours utiliser HttpServletResponse, vous pouvez l'obtenir soit injecté dans l'un des champs de classe, soit en utilisant la propriété, soit en paramètre de méthode:
@Path("/resource")
class MyResource {
// one way to get HttpServletResponse
@Context
private HttpServletResponse anotherServletResponse;
// another way
Response myMethod(@Context HttpServletResponse servletResponse) {
// ... code
}
}
@Context ServletContext ctx;
@Context private HttpServletResponse response;
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("/download/{filename}")
public StreamingOutput download(@PathParam("filename") String fileName) throws Exception {
final File file = new File(ctx.getInitParameter("file_save_directory") + "/", fileName);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() + "\"");
return new StreamingOutput() {
@Override
public void write(OutputStream output) throws IOException,
WebApplicationException {
Utils.writeBuffer(new BufferedInputStream(new FileInputStream(file)), new BufferedOutputStream(output));
}
};
}
J'ai pensé à définir l'en-tête de réponse HTTP et le flux pour afficher la fenêtre de téléchargement dans le navigateur via un servlet standard. remarque: j'utilise Excella, l'API de sortie Excel.
package local.test.servlet;
import Java.io.IOException;
import Java.net.URL;
import Java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import local.test.jaxrs.ExcellaTestResource;
import org.Apache.poi.ss.usermodel.Workbook;
import org.bbreak.excella.core.BookData;
import org.bbreak.excella.core.exception.ExportException;
import org.bbreak.excella.reports.exporter.ExcelExporter;
import org.bbreak.excella.reports.exporter.ReportBookExporter;
import org.bbreak.excella.reports.model.ConvertConfiguration;
import org.bbreak.excella.reports.model.ReportBook;
import org.bbreak.excella.reports.model.ReportSheet;
import org.bbreak.excella.reports.processor.ReportProcessor;
@WebServlet(name="ExcelServlet", urlPatterns={"/ExcelServlet"})
public class ExcelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
URL templateFileUrl = ExcellaTestResource.class.getResource("myTemplate.xls");
// /C:/Users/m-hugohugo/Documents/NetBeansProjects/KogaAlpha/build/web/WEB-INF/classes/local/test/jaxrs/myTemplate.xls
System.out.println(templateFileUrl.getPath());
String templateFilePath = URLDecoder.decode(templateFileUrl.getPath(), "UTF-8");
String outputFileDir = "MasatoExcelHorizontalOutput";
ReportProcessor reportProcessor = new ReportProcessor();
ReportBook outputBook = new ReportBook(templateFilePath, outputFileDir, ExcelExporter.FORMAT_TYPE);
ReportSheet outputSheet = new ReportSheet("MySheet");
outputBook.addReportSheet(outputSheet);
reportProcessor.addReportBookExporter(new OutputStreamExporter(response));
System.out.println("wtf???");
reportProcessor.process(outputBook);
System.out.println("done!!");
}
catch(Exception e) {
System.out.println(e);
}
} //end doGet()
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}//end class
class OutputStreamExporter extends ReportBookExporter {
private HttpServletResponse response;
public OutputStreamExporter(HttpServletResponse response) {
this.response = response;
}
@Override
public String getExtention() {
return null;
}
@Override
public String getFormatType() {
return ExcelExporter.FORMAT_TYPE;
}
@Override
public void output(Workbook book, BookData bookdata, ConvertConfiguration configuration) throws ExportException {
System.out.println(book.getFirstVisibleTab());
System.out.println(book.getSheetName(0));
//TODO write to stream
try {
response.setContentType("application/vnd.ms-Excel");
response.setHeader("Content-Disposition", "attachment; filename=masatoExample.xls");
book.write(response.getOutputStream());
response.getOutputStream().close();
System.out.println("booya!!");
}
catch(Exception e) {
System.out.println(e);
}
}
}//end class