skip to Main Content

I’m having a problem downloading a Excel file in browser using React.js.

Here is the situation:

I have written an API which will take an Excel file as input , then after modifying it using Aspose Cells I have saved it as a memorystream.Then converted it as a Byte[].
Now sending back the byte[] to the client side, then converting it as a Blob to trigger a download in browser.
An excel file is downloading but when opening it its showing corrupted. can anyone help me out ?

Here is my server side api code

public async Task<Byte[]> ExportToExcel(IFormFile file)
    {
        if (file == null || file.Length == 0)
        {
            return null;
        }
        try
        {
            using (var stream = file.OpenReadStream())
            {
                Workbook workbook = new Workbook(stream);
                var worksheet = workbook.Worksheets[0];
                Cells cells = worksheet.Cells;

                FindOptions findOptions = new FindOptions();
                findOptions.CaseSensitive = false;
                findOptions.LookInType = LookInType.Values;
                findOptions.LookAtType = LookAtType.Contains;

                // Doing modifications in Excel file....

                // Save the modified workbook as Excel file
                var excelMemoryStream = new MemoryStream();
                workbook.Save(excelMemoryStream, SaveFormat.Xlsx);
                byte[] data = excelMemoryStream.ToArray();

                return data;
                

            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }

and this is the client side code of React js

const onBtExport = () => {
const csvData = gridRef.current.api.getDataAsExcel();
console.log(csvData);
instance
  .acquireTokenSilent({
    ...accessToken,
    account: accounts[0],
  })
  .then(async (response) => {
    const formData = new FormData();
    formData.append('file', csvData);
    ExportToExcel(response.accessToken, formData).then((res) => {
      if (res.data.Status === true) {
        console.log(res.data.Data);
        const blob = new Blob([res.data.Data],{ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
        console.log(blob);
        // console.log(blob);
        const a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = 'ContractSummaryReport.xlsx';
        a.click();

        URL.revokeObjectURL(a.href);
        
      } else {
        toast.error(res.data.Message);
        
      }
    });
  });

};

3

Answers


  1. When you’re receiving the response from your API, the byte array is being returned in a format that you need to properly handle in the client-side code.

    Here’s a suggestion for the client-side code in React.js to correctly handle the byte array and trigger the download:

    const onBtExport = () => {
      const csvData = gridRef.current.api.getDataAsExcel();
      console.log(csvData);
      instance
        .acquireTokenSilent({
          ...accessToken,
          account: accounts[0],
        })
        .then(async (response) => {
          const formData = new FormData();
          formData.append('file', csvData);
          ExportToExcel(response.accessToken, formData).then((res) => {
            if (res.data.Status === true) {
              console.log(res.data.Data);
    
              // Create a Blob from the response data
              const blob = new Blob([res.data], {
                type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
              });
    
              // Create a download link
              const a = document.createElement('a');
              a.href = URL.createObjectURL(blob);
              a.download = 'ContractSummaryReport.xlsx';
              a.click();
    
              // Clean up
              URL.revokeObjectURL(a.href);
            } else {
              toast.error(res.data.Message);
            }
          });
        });
    };
    

    In this code, I removed .data.Data because the response already contains the byte array. So, we are creating a Blob from res.data itself. Make sure that the byte array returned by your API is correctly formatted.

    Login or Signup to reply.
  2. I am not sure whether the issue is with Aspose.Cells or on your client-end. To isolate the issue, you may try:

    • Save the "data" to local file on the server and then check whether
      the local file can be opened by MS Excel without problem. If not, it
      means there are some invalid data in the generated Excel file via
      Aspose.Cells and so, we need template Excel file and runnable sample
      code to reproduce the issue and to fix it.

    If yes, then the issue should be in the process at client side, so you may try:

    • Remove all invocations to APIs of Aspose.Cells, instead just reading
      the template file as byte[] and send the byte[] to client to check
      whether the received file can still be opened by MS Excel.

    This way, you can evaluate your issue thoroughly and figure it out on your end accordingly.

    You may also post your queries or discuss further in the dedicated forum.

    PS. I am working as Support developer/ Evangelist at Aspose.

    Login or Signup to reply.
  3. The issue you’re experiencing with the downloaded Excel file being corrupted could be related to how you’re sending and handling the byte data on the client side in your React.js application. To ensure a successful download and proper handling of binary data, you can follow these steps:

    1. API Response Configuration: Make sure that your API endpoint correctly sets the response headers to indicate that it’s sending binary data (in this case, the Excel file). In ASP.NET Core, for example, you can set the response content type to "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" (for Excel files) and include headers like "Content-Disposition" to suggest a filename for the downloaded file.

    Here’s an example of how to configure the API response headers in C#:

    Response.Headers.Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    Response.Headers.Add("Content-Disposition", "attachment; filename=your-excel-file.xlsx");
    
    1. Client-Side Handling: In your React.js application, ensure that you’re handling the response correctly. You can use the Blob constructor to create a Blob object from the received byte array, and then create a download link to trigger the download.

    Here’s an example of how you can handle the response in React.js:

    const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    a.download = 'file_name.xlsx';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    
    1. Check for Potential Data Transformations: Ensure that no data transformations or encodings are applied to the byte data between the API response and the creation of the Blob on the client side. The byte data should remain unchanged.

    By following these steps, you should be able to correctly download and open the Excel file without corruption in your React.js application. If you continue to experience issues, consider checking the data flow at each step and verifying that the byte data remains intact during the transmission.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search