Search code examples
reactjsazureazure-file-sharestorage-file-share

Download file from Azure Storage file share using ReactJs


I have a simple React application created using create-react-app. I have an Azure Storage named storage1, and a file share named share1. Under share1 I have a couple of files, let's say file1.pdf and file2.docx.

How can I show the list of these files and download them in the React JS application?


Solution

  • List of these files and download them in the React JS application.

    You can use the below code to list the files from Azure file share and it downloads the file to your local environment.

    First, you need to create a directory and add a file name with api.js and app.js.

    api.js

    const express = require('express');
    const { ShareServiceClient, StorageSharedKeyCredential } = require('@azure/storage-file-share');
    const axios = require('axios');
    
    const router = express.Router();
    
    const storageAccountName = "xxxx";
    const shareName = "xxxx";
    const accountKey = "xxxx";
    
    const sharedKeyCredential = new StorageSharedKeyCredential(storageAccountName, accountKey);
    const shareServiceClient = new ShareServiceClient(`https://${storageAccountName}.file.core.windows.net`, sharedKeyCredential);
    const directoryName="";
    // Route to get the list of files
    router.get('/files', async (req, res) => {
      try {
        const directoryClient = shareServiceClient.getShareClient(shareName).getDirectoryClient(directoryName);
        const list=directoryClient.listFilesAndDirectories();
        const files = [];
    
        for await (const item of list) {
          if (item.kind === 'file') {
            files.push(item.name);
          }
        }
    
        res.json(files);
      } catch (error) {
        console.error('Error listing files:', error);
        res.status(500).json({ error: 'An error occurred while listing files.' });
      }
    });
    
    async function downloadFileInBrowser(fileName) {
      const fileClient = shareServiceClient.getShareClient(shareName).rootDirectoryClient.getFileClient(fileName);
    
      // Get file content from position 0 to the end
      const downloadFileResponse = await fileClient.download(0);
      return downloadFileResponse.blobBody;
    }
    
    router.get('/download/:fileName', async (req, res) => {
      const { fileName } = req.params;
    
      try {
        const fileContent = await downloadFileInBrowser(fileName);
    
        res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
        res.setHeader('Content-Type', 'application/octet-stream');
        res.send(fileContent);
      } catch (error) {
        console.error('Error downloading file:', error);
        res.status(500).json({ error: 'An error occurred while downloading the file.' });
      }
    });
    
    module.exports = router;
    

    app.js

    const express = require('express');
    const cors = require('cors');
    const apiRouter = require('./api');
    
    const app = express();
    const port = process.env.PORT || 5000;
    
    app.use(cors());
    app.use('/api', apiRouter);
    
    app.listen(port, () => {
      console.log(`Express app listening on port ${port}`);
    });
    

    Next, In your react directory create Filelist.js

    FileList.js

    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    
    function FileList() {
      const [fileList, setFileList] = useState([]);
    
      useEffect(() => {
        async function fetchData() {
          try {
            const response = await axios.get('http://localhost:5000/api/files');
            setFileList(response.data);
          } catch (error) {
            console.error('Error fetching files:', error);
          }
        }
    
        fetchData();
      }, []);
    
      const downloadFile = async (fileName) => {
        try {
          const response = await axios.get(`http://localhost:5000/api/download/${fileName}`, { responseType: 'blob' });
          const url = window.URL.createObjectURL(new Blob([response.data]));
          const a = document.createElement('a');
          a.href = url;
          a.download = fileName;
          a.click();
          window.URL.revokeObjectURL(url);
        } catch (error) {
          console.error('Error downloading file:', error);
        }
      };
    
      return (
        <div>
          <h1>Files from Azure file share</h1>
          <ul>
            {fileList.map((file, index) => (
              <li key={index}>
                {file}
                <button onClick={() => downloadFile(file)}>Download</button>
              </li>
            ))}
          </ul>
        </div>
      );
    }
    
    export default FileList;
    

    Now we should run the backend code and it runs successfully as below,:

    enter image description here

    Then, I ran the frontend code and it also ran successfully as below,

    enter image description here

    And it opens in the browser like below. and it lists the files from Azure file share and you can click the download button to download the files.

    enter image description here

    Reference: Azure Storage File Share client library for JavaScript | Microsoft Learn