Issues with downloading the word file from Azure blob storage in the Next.js application have led to corruption

I stored the word file on azure blob storage.

Now, I am attempting to retrieve the word file in a next.js application. The file is successfully downloaded, however, when trying to open it in MS Word, an error message is displayed:

https://i.stack.imgur.com/lwTzs.png

Below is my API code:

import { dataFound, dataNotFound } from '@/helpers/api-result';
import { BlobServiceClient } from '@azure/storage-blob';

export const GET = async (request: any) => {
  try {
    const url = new URL(request.url)
    const fileName = url.searchParams.get('fileName') as string;
    let connectionString = process.env.NEXT_PUBLIC_AZURE_BLOB_STORAGE_CONNECTION_STRING
    let containerName = "xxxxxxxx"
    const blobServiceClient:any = BlobServiceClient.fromConnectionString(connectionString!);
    const containerClient:any = blobServiceClient.getContainerClient(containerName);
    const blobClient:any = containerClient.getBlobClient(fileName);
    const blobDownloadResponse = await blobClient.download();
    let blobStream:any = await blobDownloadResponse.readableStreamBody;

      const headers = {
        'Content-Disposition': `attachment; filename="${fileName}"`,
        'Content-Type': blobDownloadResponse.contentType
      };
      const data = {
        status: 200,
        headers,
        body: blobStream
      };
      return data ? dataFound(data):dataNotFound(null)

  } catch (error) {
    return {
        status: 500,
        body: 'An error occurred while downloading the file.'
      };
  }
}

And here is my JSX code:

  const data = await axios.get("/api/download", { params: { attachmentPath: attachmentPath,fileName:originalFileName },  
                responseType: "blob",
              });
             
            const blobContent = data.data;
            
            if (data.status) {
                const blob = new Blob([blobContent], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" });
                const blobUrl = URL.createObjectURL(blob);
                
                const a = document.createElement('a');
                a.href = blobUrl;
                a.download = originalFileName;
                a.click();
                URL.revokeObjectURL(blobUrl);
            }

Even after updating the content type to 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' and testing again, the issue remains unresolved.

Kindly provide assistance in resolving this problem.

Answer №1

When dealing with word files, it is important to remember that they are binary files. Attempting to convert them to a string and then back to a blob can lead to corruption. To properly handle the binary data, I used the following code to download a word blob file from Azure storage.

To begin, I uploaded a word file to my storage container on the Azure portal as shown below:

Code :

pages/api/download.js :

import { BlobServiceClient } from '@azure/storage-blob';

export default async (req, res) => {
  try {
    const { fileName } = req.query;
    const connectionString = process.env.NEXT_PUBLIC_AZURE_BLOB_STORAGE_CONNECTION_STRING;
    const containerName = '<container_name>'; 

    const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
    const containerClient = blobServiceClient.getContainerClient(containerName);
    const blobClient = containerClient.getBlobClient(fileName);

    const blobDownloadResponse = await blobClient.download();
    const blobStream = blobDownloadResponse.readableStreamBody;

    res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');

    blobStream.pipe(res);
  } catch (error) {
    console.error('Error:', error);
    res.status(500).json({ error: 'An error occurred while downloading the file.' });
  }
};

pages/index.js :

import React from 'react';

const Home = () => {
  const downloadFile = async () => {
    try {
      const fileName = '<wordfile_name>.docx'; 
      const response = await fetch(`/api/download?fileName=${fileName}`);

      // Rest of the code for handling the downloaded file
    } catch (error) {
      console.error('Error:', error);
    }
  };

  return (
    <div>
      <button onClick={downloadFile}>Download Word File</button>
    </div>
  );
};

export default Home;

components/DownloadButton.js :

import React from 'react';

const DownloadButton = ({ onClick }) => {
  return (
    <button onClick={onClick}>Download Word File</button>
  );
};

export default DownloadButton;

.env.local :

NEXT_PUBLIC_AZURE_BLOB_STORAGE_CONNECTION_STRING=<connec_string>

package.json :

{
  "name": "nextjs-azure-blob-download",
  "version": "1.0.0",
  "description": "A Next.js application for downloading Word files from Azure Blob Storage",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "@azure/storage-blob": "^12.15.0",
    "isomorphic-unfetch": "^3.1.0",
    "next": "^11.1.4",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}

Output :

The next js app runs successfully as below,

With the above URL, I downloaded the blob file in the browser as below,

Then, I opened the downloaded blob, I can see the data in the word file as below,

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search