3

I am working on a spring boot application. In my project I am creating a .xlsx file and then i have to send via email using spring boot.

I am able to create the file using apache poi but later to send it via mail as an attachment, i should save the file somewhere in local and then move the file back in while sending it as an attachment.

Is there any way in which I can create a .xlsx file and directly send it via email, without saving it somewhere first?

For mail I am using 'org.springframework.boot:spring-boot-starter-mail'

For .xlsx I am using 'org.apache.poi', name: 'poi', version: '4.1.2' and 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'.

Source Code

       XSSFWorkbook workbook = new XSSFWorkbook();
       List<String> s = Arrays.asList("person","animal");
       CellStyle style = workbook.createCellStyle();
       style.setWrapText(true);
       int n = 1;
       String source = s.get(0);
       Sheet sheet = workbook.createSheet(source);
       for (String i : s) {
           if(!source.equalsIgnoreCase(i)) {
               sheet = workbook.createSheet(i);
               Row header = sheet.createRow(0);

               CellStyle headerStyle = workbook.createCellStyle();

               XSSFFont font = workbook.createFont();
               font.setFontName("Arial");
               font.setBold(true);
               headerStyle.setFont(font);

               Cell headerCell = header.createCell(0);
               headerCell.setCellValue("Name");
               headerCell.setCellStyle(headerStyle);

               headerCell = header.createCell(1);
               headerCell.setCellValue("Age");
               headerCell.setCellStyle(headerStyle);
               source = i;
           }

           Row row = sheet.createRow(n);
           Cell cell = row.createCell(0);
           cell.setCellValue("Udhav Mohata");
           cell.setCellStyle(style);

           cell = row.createCell(1);
           cell.setCellValue(22);
           cell.setCellStyle(style);
           n++;
       }

       FileOutputStream outputStream = new FileOutputStream(Path_to_the_file);
       workbook.write(outputStream);
       workbook.close();
       sendMail();
   }


public void sendMail() throws MessagingException, IOException {
       MimeMessage message = mailSender.createMimeMessage();
       MimeMessageHelper helper = new MimeMessageHelper(message, true);
       helper.setFrom("spidercodie@gmail.com");
       helper.setTo("udhavmohata1@gmail.com");
       helper.setSubject("Test Mail");
       helper.setText("Hello world");
       FileSystemResource file = new FileSystemResource(path_to_the_file));
       helper.addAttachment("Invoice.xlsx", file);
       mailSender.send(message);
   }
Udhav Mohata
  • 99
  • 3
  • 12
  • Write to a `ByteArrayOutputStream` and pass the bytes straight to an email? – Gagravarr Sep 28 '20 at 13:38
  • @Gagravarr can you show it with a simple sample code? Thanks. – Udhav Mohata Sep 28 '20 at 13:50
  • `ByteArrayOutputStream baos = new ByteArrayOutputStream(); workbook.write(baos); byte[] data = baos.toByteArray();` – Gagravarr Sep 28 '20 at 13:58
  • @Gagravarr I dont think it will work because its not possible to pass the bytes directly to mail without saving it somewhere in a file. – Udhav Mohata Sep 29 '20 at 14:31
  • 2
    Does this answer your question? [How to send email with attachment using InputStream and Spring?](https://stackoverflow.com/questions/5677490/how-to-send-email-with-attachment-using-inputstream-and-spring). In other words, you are not limited to only using a `FileSystemResource`. – andrewJames Sep 29 '20 at 14:36
  • @andrewjames Sorry but no. – Udhav Mohata Sep 29 '20 at 19:49

1 Answers1

5

Here is my suggestion, based on the approach in the link I provided - which is essentially what Gagravarr also mentioned in his comments.

(This approach works fine for me, using gmail.)

Creating the Excel File

I used your code, except for the final part. Instead of writing your workbook to the filesystem, I wrote it to a byte array via java.io.ByteArrayOutputStream.

ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
    workbook.write(bos);
} finally {
    bos.close();
}
byte[] excelFileAsBytes = bos.toByteArray();

Using my Byte Array as an Attachment

In my e-mailer code (which is almost identical to yours, but I did not want to copy/paste your e-mail address by accident), I replaced these lines:

FileSystemResource file = new FileSystemResource(path_to_the_file));
helper.addAttachment("Invoice.xlsx", file);

with these lines, using a org.springframework.core.io.ByteArrayResource:

ByteArrayResource resource = new ByteArrayResource(excelFileAsBytes);
helper.addAttachment("Invoice.xlsx", resource);

That gives me an e-mail containing the Excel file as an attachment.

andrewJames
  • 19,570
  • 8
  • 19
  • 51