How to export a xlsx file from frontend (react) to backend (express), and then send it to email?

3 min read 26-09-2024
How to export a xlsx file from frontend (react) to backend (express), and then send it to email?


In modern web development, the need to handle files—particularly spreadsheet files like XLSX—has become increasingly common. In this article, we will walk through the process of exporting an XLSX file from a React frontend, sending it to an Express backend, and then dispatching it as an email attachment. We will cover the necessary code snippets, explain the logic, and provide practical insights along the way.

Problem Scenario

Imagine you have a React application where users can create and download reports as XLSX files. However, instead of allowing users to download the file directly, you want to send it to a specified email address. This involves exporting the file from the React frontend, sending it to an Express backend, and then using a mailing service to send the file to the user's email.

Here is a simplified code snippet that illustrates the initial step of exporting the XLSX file in React:

// React Component to Export XLSX
import React from 'react';
import XLSX from 'xlsx';

const ExportButton = () => {
  const exportXLSX = () => {
    // Sample data to export
    const data = [
      { Name: 'John Doe', Age: 30, Email: '[email protected]' },
      { Name: 'Jane Doe', Age: 25, Email: '[email protected]' },
    ];

    // Create a new workbook and add the data
    const workbook = XLSX.utils.book_new();
    const worksheet = XLSX.utils.json_to_sheet(data);
    XLSX.utils.book_append_sheet(workbook, worksheet, 'Report');

    // Export the XLSX file as a Blob
    const xlsxFile = XLSX.writeFile(workbook, 'report.xlsx');
    
    // The next step would be to send this file to the backend
  };

  return <button onClick={exportXLSX}>Export to XLSX</button>;
};

export default ExportButton;

Step-by-Step Guide

1. Setting Up the React Frontend

In the example code above, we create a button that, when clicked, exports sample data to an XLSX file. The next step involves sending this file to your Express backend.

To send the file to your backend, you can use the FormData API:

const exportXLSX = () => {
  const data = [
    { Name: 'John Doe', Age: 30, Email: '[email protected]' },
    { Name: 'Jane Doe', Age: 25, Email: '[email protected]' },
  ];

  const workbook = XLSX.utils.book_new();
  const worksheet = XLSX.utils.json_to_sheet(data);
  XLSX.utils.book_append_sheet(workbook, worksheet, 'Report');

  const xlsxFile = XLSX.write(workbook, { bookType: 'xlsx', type: 'binary' });
  
  // Create Blob and FormData to send to backend
  const blob = new Blob([s2ab(xlsxFile)], { type: 'application/octet-stream' });
  const formData = new FormData();
  formData.append('file', blob, 'report.xlsx');

  // Send to backend using fetch API
  fetch('/api/send-email', {
    method: 'POST',
    body: formData,
  })
    .then((response) => response.json())
    .then((data) => {
      console.log('File sent successfully:', data);
    })
    .catch((error) => {
      console.error('Error sending file:', error);
    });
};

// Utility function to convert string to array buffer
function s2ab(s) {
  const buf = new ArrayBuffer(s.length);
  const view = new Uint8Array(buf);
  for (let i = 0; i < s.length; i++) {
    view[i] = s.charCodeAt(i) & 0xFF;
  }
  return buf;
}

2. Setting Up the Express Backend

Now let's set up the Express backend to handle the file sent from React. You’ll need to install necessary packages:

npm install express multer nodemailer

Here’s a simple Express setup:

// server.js
const express = require('express');
const multer = require('multer');
const nodemailer = require('nodemailer');
const app = express();
const port = process.env.PORT || 5000;

// Multer setup to handle file uploads
const upload = multer({ dest: 'uploads/' });

// POST route to send email with the attachment
app.post('/api/send-email', upload.single('file'), (req, res) => {
  const transporter = nodemailer.createTransport({
    service: 'gmail', // or other email service
    auth: {
      user: '[email protected]',
      pass: 'your-email-password',
    },
  });

  const mailOptions = {
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Here is your XLSX file',
    text: 'Please find the attached report.',
    attachments: [
      {
        path: req.file.path, // file sent from frontend
      },
    ],
  };

  transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      return res.status(500).send(error.toString());
    }
    res.status(200).send('Email sent: ' + info.response);
  });
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

Additional Insights and Best Practices

  1. Security Considerations: Ensure you handle sensitive data securely. Avoid hardcoding email credentials and use environment variables instead.

  2. Error Handling: Implement comprehensive error handling to cover various failure scenarios, such as file upload failures or email sending issues.

  3. Email Service Providers: Consider using services like SendGrid or Mailgun for more robust email capabilities, especially if you're handling high volumes.

  4. File Storage: You might want to clean up files after they’ve been sent to avoid filling your server with unnecessary data.

Conclusion

By following the steps outlined above, you can effectively export an XLSX file from a React frontend, send it to an Express backend, and deliver it via email. This approach allows you to streamline the process of file handling in your applications.

Useful Resources

Implement these techniques in your project to add enhanced file exporting and emailing capabilities. Happy coding!