2026-07-15

Sending an e-mail through java application with excel file attached - not working

Stefan Bogdanescu

Stefan Bogdanescu

Founder & Senior Architect

Sending an e-mail through java application with excel file attached - not working

Sending Excel Attachments via Java Email: Why Your Tab-Delimited File Fails

As a senior developer, I often encounter scenarios where the intent of the application doesn't match the final output. You are trying to send an email with an attachment, and while you can successfully attach a file, the format is incorrect—you have data separated by tabs, but you want a genuine Microsoft Excel file (.xlsx).

The issue you are facing stems from a fundamental misunderstanding of how email attachments handle file formats versus plain text data in Java applications. Simply treating tab-separated data as an application/vnd.ms-excel stream results in a text file masquerading as an Excel spreadsheet, which most mail clients cannot correctly interpret as a functional Excel workbook.

This post will diagnose why your current approach fails and provide the correct, robust methodology using established Java libraries to generate true Excel files before sending them via email.


The Root Cause: Text vs. Binary Data

When you use new ByteArrayDataSource(data, "application/vnd.ms-excel"), you are telling the mail server that the data stream contains plain text, delimited by tabs (\t). While some older systems might attempt to render this as a simple tab-separated values (TSV) file, they do not recognize the binary structure required for modern Excel files (.xlsx or .xls).

Excel files are not simple text files; they are complex, structured binary archives (Open XML format for .xlsx). To send a valid attachment, you must generate the actual binary content of an Excel file and attach that byte stream to the message.

The Solution: Generating True Excel Files with Apache POI

To solve this, instead of manually concatenating strings with tabs, you need a dedicated library to handle the complex formatting required for spreadsheet creation. The industry standard in Java for working with Microsoft Office formats is Apache POI.

POI allows you to programmatically create .xlsx files directly from your database query results, ensuring the attachment is valid and usable by any modern email client.

Step-by-Step Implementation Guide

Here is the conceptual process you should follow:

  1. Fetch Data: Retrieve your data from the database as a ResultSet.
  2. Create Workbook: Use Apache POI to create a new Excel workbook (XSSFWorkbook for .xlsx).
  3. Populate Rows: Iterate through your database results and write the data into the corresponding cells of the spreadsheet.
  4. Write File: Write the completed workbook object to an in-memory byte array (a stream).
  5. Attach to Email: Use this byte array as the data source for your MimeMessage.

Java Code Example (Conceptual using POI)

The following example demonstrates how to replace the manual string concatenation with a proper file generation process. Note that this requires adding the Apache POI dependency to your project.

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.xml.bind.JAXBContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;

// Assume 'rs' is your ResultSet from the database query

public void sendExcelEmail(ResultSet rs, Session session) throws Exception {
    // 1. Create a new workbook
    Workbook workbook = new XSSFWorkbook();
    Sheet sheet = workbook.createSheet("Data");

    // 2. Create Header Row (Optional but recommended)
    Row headerRow = sheet.createRow(0);
    headerRow.createCell(0).setCellValue("Column 1");
    headerRow.createCell(1).setCellValue("Column 2");
    // ... create headers for all columns

    // 3. Populate Data Rows
    Iterator<java.sql.ResultSet.ResultSetIterator> iterator = rs.setFetchDirection(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    while (iterator.hasNext()) {
        java.sql.ResultSet.Row row = iterator.next();
        Row row = sheet.createRow(sheet.getLastRowNum() + 1);

        // Populate data based on database columns
        row.createCell(0).setCellValue(row.getString("ColumnName1")); // Replace with actual column names
        row.createCell(1).setCellValue(row.getDouble("ColumnName2"));
        // ... continue for all columns
    }

    // 4. Write the Workbook to a Stream (Byte Array)
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        workbook.write(baos);
        byte[] excelBytes = baos.toByteArray();

        // 5. Attach the true Excel file data to the MimeMessage
        MimeMessage msg = new MimeMessage(session);
        // ... set To, From details ...

        MimeBodyPart mbp1 = new MimeBodyPart();
        // Set content type to the correct XLSX MIME type
        mbp1.setData(new ByteArrayResource(excelBytes));
        mbp1.setFileName("database_report_" + System.currentTimeMillis() + ".xlsx");

        MimeMultipart mp = new MimeMultipart();
        mp.addBodyPart(mbp1);
        // Add other body parts if needed (e.g., plain text introduction)
        msg.setContent(mp);
        msg.saveChanges();
        Transport.send(msg);

    } catch (IOException e) {
        throw new RuntimeException("Error writing Excel file", e);
    }
}

Conclusion

The experience you encountered is a common pitfall when dealing with file attachments over email: confusing raw data serialization with actual file format generation. Never rely on simple string manipulation to create complex file types like .xlsx. By integrating powerful libraries like Apache POI, you ensure that your Java application generates legally structured binary files, leading to reliable and professional communication. For building robust backend systems, especially those interfacing with external services or protocols, adopting these high-quality tools is essential, much like the architecture principles found in enterprise frameworks like those promoted by Laravel.

Tags:

Enhance your marketing setup with your own email marketing platform.

Join the growing number of SaaS platforms using Laravel Mail to offer email marketing solutions to their customers.