-1

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);
        
      }
    });
  });

};

  • 1
    The client code uses the wrong extension, xls instead of xlsx. `xls` was used before 2007 and is a completely different format from `xlsx`, a ZIP package containing XML files.. As far as Excel is concerned yes, the file is corrupt because it says it uses the pre-2006 `xls` format but contains something else – Panagiotis Kanavos Aug 25 '23 at 07:09
  • It would be a *lot* better to return the data as a FileStreamResult with the correct content type and possibly a filename, instead of bytes. First, move the stream position to the start then `return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","ContractSummaryReport.xlsx");`. In the client code use the file name and content type returned in the response – Panagiotis Kanavos Aug 25 '23 at 07:12
  • @PanagiotisKanavos thanks for the quick response, but the problem is I have tried `return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","ContractSummaryReport.xlsx");` this line but its showing error Non-invocable member 'File' cannot be used like a method. – Suprateem Bose Aug 25 '23 at 07:17
  • `File` works in all Controller actions as it's defined in `ControllerBase`. In the action that actually returns the file you can use `File(bytes,.....)`. – Panagiotis Kanavos Aug 25 '23 at 07:31
  • In any case, to isolate the error you should try saving the file to disk first in your .NET code. If that works, call the API with eg POSTMAN or, if you use GET, the browser itself, and check if the returned file can be opened. If you use `File(...)` with the correct type and a name, the browser will download the file with that name. I suspect both these steps will work. – Panagiotis Kanavos Aug 25 '23 at 07:34

1 Answers1

0

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.

Amjad Sahi
  • 1,813
  • 1
  • 10
  • 15