0
votes

When I created a File in SpringBoot (I can get File with data in my desktop) I am tryied send this File to Angular2 but When my File arrive , I get NULL in Angular2.

SpringBoot:

Here, I call to SpringBOOT for download Excell.

@RequestMapping(method = RequestMethod.GET, path = "/{download}", produces = MediaType.APPLICATION_JSON_VALUE)
    public MultipartFile download() {

        MultipartFile myFile = null;
        myFile = downloadExcell();

        return myFile;
    }

In this function I created myExcell ,My excell is created success, I can get file in my desktop.

private MultipartFile downloadExcell() {
        MultipartFile myFile = null;
        String eyelash = "People";

        try {
            String filename = pathTempdownloadFile;

            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet(eyelash);

            String [] header= {"YEAR","MONTH","NAME","SURNAME","TLF"} ;
            HSSFRow rowhead = sheet.createRow((short) 0);


            for (int i = 0; i < header.length; i++) {
                cell = rowhead.createCell(cellnum);
                cell.setCellValue(header[i]);
                cellnum++;
            }

            FileOutputStream fileOut = new FileOutputStream(filename);
            workbook.write(fileOut);
            fileOut.close();
            workbook.close();

        } catch (Exception ex) {
            System.out.println(ex);
        }

        return myFile;
    }

Now I have that to assign fileOut to myFile

myFile = (MultipartFile) fileOut;

Error ->

java.lang.ClassCastException: java.io.FileOutputStream cannot be cast to org.springframework.web.multipart.MultipartFile

Finally I get (false) in Angular2 myFile.

Angular2->

  downloadFile() {
    this.service.downloadFile().subscribe(data => {
      console.log("FILE", data);
    });
  }

 downloadFile() {
     const url = "http://localhost:8080/ml/download";
     return this.http.get(url);
  }

I need send the Excell the SpringBoot to Angular2, but I don't found how do. Ty

2

2 Answers

1
votes

As you already learned, MultipartFile and FileOutputStream are unrelated: as you can see from the instantiation, the output stream was created and used to write to a file, not to your servlet response, and MultipartFile is usually used as a request parameter but can't be used for the response.

Depending on you requirements, you could write the Excel file directly to the web requests output stream. However, I believe it is good practice to store it in the file system first and then serve it from there.

In order to access the response, you can inject the HttpServletResponse into the controller method (Spring takes care to fill this parameter properly):

public void download(HttpServletResponse response)

Also note that I've changed the return type to void, as you'll be working with the response parameter only.

After storing your file, you can now write it to the response. Remember to set the proper content type as part of the response, so that the requesting client, e.g. the browser, knows how to deal with it.

    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setHeader("Content-disposition", "attachment; filename=result.xlsx");
    try (final InputStream is = new FileInputStream(filename)) {
        IOUtils.copy(is, response.getOutputStream());
        response.flushBuffer();
    } catch (Exception ex) {
        // deal with error, e.g. response.setStatus(500) to signal an internal server error
    }

Note that I've used IOUtils.copy from the Apache Commons IO library. It simply copies input bytes from the FileInputStream to the response OutputStream, you can implement this manually as well:

    byte[] buffer = new byte[4096];
    OutputStream os = response.getOutputStream();
    for (long count = 0L; -1 != (n = is.read(buffer)); count += (long)n) {
        os.write(buffer, 0, n);
    }

Also note that I've specified another header, Content-Disposition. This provides additional guidance for the browser on how to deal with the received file; attachment usually leads to a save dialog, while inline produces an inline display of the file (interesting e.g. for PDFs). The specified filename will be used by the browser to store the file.

2
votes

You should not directly send file from spring boot. This disturbs the traffic on the server. I suggest you to upload the file to any static file hosting like S3. And then send the URL of the file to angular. Let angular fetch it from S3.