Search code examples
c#closedxml

How to export an Excel document through a server?


I made a simple web page with some data that can be manipulated and i used ClosedXML to convert that list to an exel document. The data manipulation works fine. The problem is with the Excel conversion.

How am i supposed to program the web page to save the document on the client side? The code bellow works locally, when i test it on my PC, but trying to do that remotly on the server prompts an error.

Runtime Error Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.

Details: To enable the details of this specific error message to be viewable on remote machines, please create a tag within a "web.config" configuration file located in the root directory of the current web application. This tag should then have its "mode" attribute set to "Off".

I'm not familiar how to make a custom error, yet, but i do get the fact that the problem must be the way i try to save the file. The app tries to save the document on the server's C disk. While i need it to save the file on the client's PC.

View:

@using (Html.BeginForm("Export", "Home"))
{
    <button class="btn btn-primary btn" type="submit" name="dummy" value="">Export Excel</button>
}

Controller:

public ActionResult Export() //Export Excel
{
    if (staticList.Count > 0)
    {
        // here be the convertion of the data to Excel using ClosedXML
        wb.SaveAs("C:\\BT.xlsx");
        ViewData["sentence"] = "Export made";
    }
    return View("Index", staticList);
}

Solution

  • The Inserting Tables doc page shows how you can load a List directly into a spreadsheet using InsertTable, using the property names as columns. The method returns a table object that can be used to apply styles, sorting etc :

      var list = new List<Person>();
      ...
      var peopleTable= ws.Cell(7, 6).InsertTable(list);
      ...
      peopleTable.Theme = XLTableTheme.TableStyleLight10;
    
      wb.SaveAs("InsertingData.xlsx");
    

    To return the data to the caller, save the workbook to a MemoryStream and return it using File method instead of View:

    public ActionResult Export() 
    {
    
    ...
        using var stream = new System.IO.MemoryStream();
        wb.SaveAs(stream);
        var content = stream.ToArray();
    
        return File(content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "People.xlsx");
    }