0

I'm using Spring (Boot) framework for this project. Right now I'm trying to implement a functionality where the user clicks a button (generate file) and this makes him download said file. At the moment I've only managed to generate the excel file in a directory of my choosing but this is not what I want. I want the excel file to start downloading after the user clicks the button. I've seen many threads about this most have outdated solutions or don't fit with what I need. I'm doing this on a void method, I don't want a response type method if possible. Here's my code so far (excel file created with apache poi):

Controller that asks the service to generate the file:

@GetMapping("{tableId}/generateCvlList")
public void generateCvlList(@PathVariable(value = "tableId") String tableId, String sourceLanguage, String targetLanguage) {
    vpTranslationServiceI.generateCvlList(tableId, sourceLanguage, targetLanguage); 
    LOG.info("done");
}

Service that gets the data needed and names the file. Calls the class where I actually created the excel file (ExcelUtils)

@Override
public void generateCvlList(String tableId, String sourceLanguage, String targetLanguage) {
    List<TranslationsGeneratorModel> translationsGenModelList = vpCodeTranslationDao.getTranslationsForSourceAndTarget(tableId, sourceLanguage, targetLanguage);
    String fileName = "language_cvl_"+sourceLanguage+"_to_"+targetLanguage+".xlsx";
    try {
        ExcelUtils.createExcelFile(fileName, translationsGenModelList);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

The class that created and saved the excel file in R:\ folder (which I don't want):

public static void createExcelFile(String fileName, List<TranslationsGeneratorModel> translationsGenModelList) throws FileNotFoundException {
    Workbook workbook = new XSSFWorkbook();
    Sheet sheet = workbook.createSheet("language_cvl_translation");
    FileOutputStream out = new FileOutputStream(new File("R:\\"+fileName));

    ...
    ...
    ...

    try {
        workbook.write(out);
        out.close();
        workbook.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println(fileName + "written successfully");
}
  • I would apply one answer from: https://stackoverflow.com/questions/5690228/spring-mvc-how-to-return-image-in-responsebody – charlie_pl Aug 03 '17 at 11:39

1 Answers1

0

You can include HttpResponse in your controller's method

@GetMapping("{tableId}/generateCvlList")
public void generateCvlList(@PathVariable(value = "tableId") String tableId, String sourceLanguage, String targetLanguage, HttpResponse  response) {

Get output stream from the response and pass to the generation method where the output stream should be used instead of the this

FileOutputStream out = new FileOutputStream(new File("R:\\"+fileName));

You can write your excel to the response's output.

The only reason you might need files when report generation needs significant time and your request can get timeout.

If you generate big files and the process is time consuming then the files are necessary. After generating the file (name could be created from UUID) the file name is sent in response to be download later.

In this case you need more complex logic to remove downloaded files (or after some time), to notify user about report creation progress etc.

StanislavL
  • 56,971
  • 9
  • 68
  • 98