Click here to Skip to main content
15,881,588 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I want to export some complex data into excel sheet which takes more time and block application so that user cannot proceed further until this task has completed so i have used backgroundworker for that but still it block application and user has to wait until export functionality will completed. Is there any other approaches available for that or what should i change in my code to implement it? to export data into excel i am using ClosedXML Library and my application is on .net 4.0

What I have tried:

<%@ Page Title="" Language="C#" MasterPageFile="~/export_module.master"
AutoEventWireup="true" CodeFile="GenerateReport.aspx.cs"
Inherits="" Async="true" %>


public readonly BackgroundWorker worker = new BackgroundWorker();

protected void Page_Load(object sender, EventArgs e)
{
 if (!Page.IsPostBack)
    {
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;
        worker.DoWork += new DoWorkEventHandler(DoWork);
        //worker.ProgressChanged += new ProgressChangedEventHandler(WorkerProgressChanged);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(WorkerCompleted);
    }
}

protected void btn_Export_Click(object sender, EventArgs e)
  {        
    if (!worker.IsBusy){
      worker.RunWorkerAsync("ExportReport");
    }
  }     


 private void DoWork(object sender, DoWorkEventArgs e)
  {
    exportToExcel();
  }

  private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  { 
  }

 public void ExportReportWithHeaderClosedXML(string reportName, string fileName,  DataTable dataTable)
{
    int usedCells = dataTable.Columns.Count;
    string ReportDate = string.Empty;
    string attachment = "inline;filename=" + fileName + ".xlsx";
    using (XLWorkbook wb = new XLWorkbook())
    {

        //Add method of ClosedXML class library only accepts worksheet name of 31 characters.

        IXLWorksheet worksheet = wb.Worksheet(1);           

        //Insert Report Data
        worksheet.Cell(4, 1).InsertTable(dataTable);
        HttpContext.Current.Response.Clear();

        HttpContext.Current.Response.ClearContent();
        HttpContext.Current.Response.ClearHeaders();
        HttpContext.Current.Response.Buffer = true;

        HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "inline;filename=" + fileName + ".xlsx");
        using (MemoryStream MyMemoryStream = new MemoryStream())
        {
            wb.SaveAs(MyMemoryStream);
            MyMemoryStream.WriteTo(HttpContext.Current.Response.OutputStream);
            HttpContext.Current.Response.End();
        }
    }
}
Posted
Updated 4-Apr-19 2:32am
v4

1 solution

There's no point in using a BackgroundWorker for this. It won't make any difference - the browser will be stuck waiting for the response from the server until the server sends the response. Pushing the code that generates the response onto a background thread will just put more strain on the server, without affecting what happens on the client.

If you want the user to be able to continue interacting with your site whilst the Excel file is being generated, you're going to need to make some changes:
  • The Excel generation needs to happen in a separate handler - preferably a "generic handler" (.ashx file).
  • The handler which generates the Excel file needs to disable session state. If you don't, other requests from the same session will be blocked until the handler finishes.
  • Replace the <asp:Button> which currently triggers the download with a <asp:HyperLink> pointing to the Excel handler.
  • Set target="_blank" on the HyperLink so that the link opens in a new tab. If you don't, the browser will freeze the current page until the navigation is complete.

This is by no means perfect - the user will see a blank tab whilst the download is being generated, and will have to switch back to the previous tab to continue interacting with your site. If they close the blank tab, the download will be cancelled.

A better option would be to work out why your export is taking so long, and find a way to speed it up. This would require you to profile your code to find the bottleneck.
 
Share this answer
 
Comments
shah.nilang 5-Apr-19 6:19am    
Can you provide example of it as i am not able to export file from handler?
Richard Deeming 5-Apr-19 7:40am    
Something like this:
<%@ WebHandler Language="C#" %>

using System;
using System.Data;
using System.Web;
using ClosedXML.Excel;
// TODO: Add other required namespaces here...

public class ExcelReportHandler : IHttpHandler
{
    public bool IsReusable
    {
        get { return false; }
    }
    
    public void ProcessRequest (HttpContext context)
    {
        DataTable reportData = LoadReportData(context);
        string fileName = "...Your filename here...";
        string reportName = "...Your report name here...";
        
        using (XLWorkbook wb = CreateReport(reportName, reportData))
        {
            context.Response.ContentType = "application/vnd.ms-excel";
            context.Response.AddHeader("Content-Disposition", "inline;filename=" + fileName + ".xlsx");
            
            using (MemoryStream ms = new MemoryStream())
            {
                wb.SaveAs(ms);
                ms.Seek(0L, SeekOrigin.Begin);
                ms.WriteTo(context.Response.OutputStream);
            }
        }
    }
    
    private static XLWorkbook CreateReport(string reportName, DataTable dataTable)
    {
        XLWorkbook wb = new XLWorkbook();
        IXLWorksheet worksheet = wb.Worksheet(1);
        worksheet.Cell(4, 1).InsertTable(dataTable);
        return wb;
    }
    
    private static DataTable LoadReportData(HttpContext context)
    {
        ...Load the report data here...
    }
}
shah.nilang 8-Apr-19 2:30am    
Process was completed successfully but file is not downloading

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900