Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Data Export to Excel using HSSFWorkbook Works Locally but Not on Test

Data Export to Excel using HSSFWorkbook Works Locally but Not on Test

Scheduled Pinned Locked Moved C#
asp-netcsharpdotnethostingregex
5 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Fokwa Divine
    wrote on last edited by
    #1

    I am new to ASP.NET Core. I have written a code that works on my local computer but when I publish the app to our test environment the behavior is strange. The scenario is as follows: When the user clicks a link, the app exports data to an excel file which is downloaded. On my PC / dev env, the data is downloaded fine and you can see it on the Excel sheet however on Test, it is rather the webpage that is on the Excel sheet hence giving a message "The file format and extension of summary.xls don't match. The file could be corrupted or unsafe" when you open the Excel file. Find below my code: In ReportController.cs

    [HttpGet]
    public ActionResult ExportSummaryToExcel(string startDate, string endDate, string postalCode)
    {
    string strStartDate = startDate;
    string strEndDate = endDate;
    string strRequestedPostalCode = postalCode;

    ViewBag.StartDate = startDate;
    ViewBag.EndDate = endDate;
    ViewBag.RequestedPostalCode = postalCode;
    
    DataTable rsReportDataByPostalCode = \_summaryByAgeStagePostalCodeService.
        GetSummaryByPostalCode(strStartDate + " 00:00:00.000000000", strEndDate + " 23:59:59.000000000", strRequestedPostalCode);
    
    ReportViewModel reportViewModel = new ReportViewModel();
    
    reportViewModel.ReportDataByPostalCodeTable = rsReportDataByPostalCode;
    
    return View("\_ExportSummaryToExcel", reportViewModel);
    

    }

    In _ExportSummaryToExcel.cshtml

    @using System.Data;
    @using BHTS.Service;
    @using Microsoft.AspNetCore.Hosting;
    @using NPOI.HSSF.UserModel;
    @using NPOI.SS.UserModel;
    @using NPOI.Util;
    @using System.IO;
    @using Microsoft.AspNetCore.Http;
    @using System.Web;
    @using NPOI.XSSF.UserModel;
    @inject IHostingEnvironment _hostingEnvironment
    @inject IHttpContextAccessor HttpContextAccessor
    @model BHTS.Service.ViewModels.ReportViewModel

    @{
    //Set the content type header with the razor directive
    Context.Response.ContentType = "application/vnd.ms-excel";

    // Set the content disposition header
    Context.Response.Headers.Add("Content-Disposition", "attachment; filename=\\"Summary.xls\\"");    
    

    }

    @{
    string strExceptionMessage ;

    try{
    
        string strNewPostalCode = "";
    
        string strRequestedPostalCode = "";         
        string strStartDate = "";
        string strEndDate = "";
    
        //Get the postal code, start date and end date for the requested data.
        strRequestedPostalCode = ViewBag.RequestedPostalCode;
        strStartDate = ViewBa
    
    R R 2 Replies Last reply
    0
    • F Fokwa Divine

      I am new to ASP.NET Core. I have written a code that works on my local computer but when I publish the app to our test environment the behavior is strange. The scenario is as follows: When the user clicks a link, the app exports data to an excel file which is downloaded. On my PC / dev env, the data is downloaded fine and you can see it on the Excel sheet however on Test, it is rather the webpage that is on the Excel sheet hence giving a message "The file format and extension of summary.xls don't match. The file could be corrupted or unsafe" when you open the Excel file. Find below my code: In ReportController.cs

      [HttpGet]
      public ActionResult ExportSummaryToExcel(string startDate, string endDate, string postalCode)
      {
      string strStartDate = startDate;
      string strEndDate = endDate;
      string strRequestedPostalCode = postalCode;

      ViewBag.StartDate = startDate;
      ViewBag.EndDate = endDate;
      ViewBag.RequestedPostalCode = postalCode;
      
      DataTable rsReportDataByPostalCode = \_summaryByAgeStagePostalCodeService.
          GetSummaryByPostalCode(strStartDate + " 00:00:00.000000000", strEndDate + " 23:59:59.000000000", strRequestedPostalCode);
      
      ReportViewModel reportViewModel = new ReportViewModel();
      
      reportViewModel.ReportDataByPostalCodeTable = rsReportDataByPostalCode;
      
      return View("\_ExportSummaryToExcel", reportViewModel);
      

      }

      In _ExportSummaryToExcel.cshtml

      @using System.Data;
      @using BHTS.Service;
      @using Microsoft.AspNetCore.Hosting;
      @using NPOI.HSSF.UserModel;
      @using NPOI.SS.UserModel;
      @using NPOI.Util;
      @using System.IO;
      @using Microsoft.AspNetCore.Http;
      @using System.Web;
      @using NPOI.XSSF.UserModel;
      @inject IHostingEnvironment _hostingEnvironment
      @inject IHttpContextAccessor HttpContextAccessor
      @model BHTS.Service.ViewModels.ReportViewModel

      @{
      //Set the content type header with the razor directive
      Context.Response.ContentType = "application/vnd.ms-excel";

      // Set the content disposition header
      Context.Response.Headers.Add("Content-Disposition", "attachment; filename=\\"Summary.xls\\"");    
      

      }

      @{
      string strExceptionMessage ;

      try{
      
          string strNewPostalCode = "";
      
          string strRequestedPostalCode = "";         
          string strStartDate = "";
          string strEndDate = "";
      
          //Get the postal code, start date and end date for the requested data.
          strRequestedPostalCode = ViewBag.RequestedPostalCode;
          strStartDate = ViewBa
      
      R Offline
      R Offline
      Ron Nicholson
      wrote on last edited by
      #2

      I'm doing something similar with product called Gembox. In a nutshell, I create the excel file and save it to a path under the website. In my case it is normally a folder called ExcelTemp. I save the file to that folder then use the following code to save it on the enduser's pc. This code will prompt them to save it unless the browser is set to automatically put it somewhere.

      		Response.Clear();
      		Response.Buffer = true;
      		Response.ContentType = "application/vnd.ms-excel";
      		Response.AddHeader("Content-Disposition", "attachment;filename=" + System.IO.Path.GetFileName(fileName));
      		Response.Charset = "";
      		Response.WriteFile(fileName);
      		Response.End();
      

      The code need the fileName as a string. HTH

      Jack of all trades, master of none, though often times better than master of one.

      1 Reply Last reply
      0
      • F Fokwa Divine

        I am new to ASP.NET Core. I have written a code that works on my local computer but when I publish the app to our test environment the behavior is strange. The scenario is as follows: When the user clicks a link, the app exports data to an excel file which is downloaded. On my PC / dev env, the data is downloaded fine and you can see it on the Excel sheet however on Test, it is rather the webpage that is on the Excel sheet hence giving a message "The file format and extension of summary.xls don't match. The file could be corrupted or unsafe" when you open the Excel file. Find below my code: In ReportController.cs

        [HttpGet]
        public ActionResult ExportSummaryToExcel(string startDate, string endDate, string postalCode)
        {
        string strStartDate = startDate;
        string strEndDate = endDate;
        string strRequestedPostalCode = postalCode;

        ViewBag.StartDate = startDate;
        ViewBag.EndDate = endDate;
        ViewBag.RequestedPostalCode = postalCode;
        
        DataTable rsReportDataByPostalCode = \_summaryByAgeStagePostalCodeService.
            GetSummaryByPostalCode(strStartDate + " 00:00:00.000000000", strEndDate + " 23:59:59.000000000", strRequestedPostalCode);
        
        ReportViewModel reportViewModel = new ReportViewModel();
        
        reportViewModel.ReportDataByPostalCodeTable = rsReportDataByPostalCode;
        
        return View("\_ExportSummaryToExcel", reportViewModel);
        

        }

        In _ExportSummaryToExcel.cshtml

        @using System.Data;
        @using BHTS.Service;
        @using Microsoft.AspNetCore.Hosting;
        @using NPOI.HSSF.UserModel;
        @using NPOI.SS.UserModel;
        @using NPOI.Util;
        @using System.IO;
        @using Microsoft.AspNetCore.Http;
        @using System.Web;
        @using NPOI.XSSF.UserModel;
        @inject IHostingEnvironment _hostingEnvironment
        @inject IHttpContextAccessor HttpContextAccessor
        @model BHTS.Service.ViewModels.ReportViewModel

        @{
        //Set the content type header with the razor directive
        Context.Response.ContentType = "application/vnd.ms-excel";

        // Set the content disposition header
        Context.Response.Headers.Add("Content-Disposition", "attachment; filename=\\"Summary.xls\\"");    
        

        }

        @{
        string strExceptionMessage ;

        try{
        
            string strNewPostalCode = "";
        
            string strRequestedPostalCode = "";         
            string strStartDate = "";
            string strEndDate = "";
        
            //Get the postal code, start date and end date for the requested data.
            strRequestedPostalCode = ViewBag.RequestedPostalCode;
            strStartDate = ViewBa
        
        R Offline
        R Offline
        Richard Deeming
        wrote on last edited by
        #3

        Fokwa Divine wrote:

        Also, we have checked the logs and there are no error messages to help point us to the root cause of the issue

        Well, that's hardly surprising - your code swallows any exceptions that are thrown! :doh:

        Fokwa Divine wrote:

        catch (Exception ex)
        {
        // Exception is swallowed; no details will be logged.
        }

        At a guess, the server has response buffering turned off for performance reasons. As a result, the Stream returned from Context.Response.Body is not "seekable", and the wb.Write call is failing for that reason. Looking through the NPOI examples repo[^], you should write the workbook to a MemoryStream first, then copy that to the response. Also, there's no need to use HttpContextAccessor within your view; you already have access to the current response via the Context.Response property. I would strongly recommend generating the workbook in your controller, or preferable a service that you call from your controller, and sending it back to the client in a custom response type. For example:

        public HSSFExcelResult : FileStreamResult
        {
        private const ExcelMimeType = "application/vnd.ms-excel";

        private static Stream SaveWorkbook(HSSFWorkbook workbook)
        {
            ArgumentNullException.ThrowIfNull(workbook);
            
            MemoryStream ms = new();
            workbook.Write(ms);
            ms.Seek(0L, SeekOrigin.Begin);
            return ms;
        }
        
        public HSSFExcelResult(HSSFWorkbook workbook) : base(SaveWorkbook(workbook), ExcelMimeType)
        {
        }
        

        }

        [HttpGet]
        public ActionResult ExportSummaryToExcel(string startDate, string endDate, string postalCode)
        {
        HSSFWorkbook workbook = _summaryByAgeStagePostalCodeService.ExportSummaryToExcel(startDate, endDate, postalCode);
        return new HSSFExcelResult(workbook) { FileDownloadName = "Summary.xls" };
        }


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        F 1 Reply Last reply
        0
        • R Richard Deeming

          Fokwa Divine wrote:

          Also, we have checked the logs and there are no error messages to help point us to the root cause of the issue

          Well, that's hardly surprising - your code swallows any exceptions that are thrown! :doh:

          Fokwa Divine wrote:

          catch (Exception ex)
          {
          // Exception is swallowed; no details will be logged.
          }

          At a guess, the server has response buffering turned off for performance reasons. As a result, the Stream returned from Context.Response.Body is not "seekable", and the wb.Write call is failing for that reason. Looking through the NPOI examples repo[^], you should write the workbook to a MemoryStream first, then copy that to the response. Also, there's no need to use HttpContextAccessor within your view; you already have access to the current response via the Context.Response property. I would strongly recommend generating the workbook in your controller, or preferable a service that you call from your controller, and sending it back to the client in a custom response type. For example:

          public HSSFExcelResult : FileStreamResult
          {
          private const ExcelMimeType = "application/vnd.ms-excel";

          private static Stream SaveWorkbook(HSSFWorkbook workbook)
          {
              ArgumentNullException.ThrowIfNull(workbook);
              
              MemoryStream ms = new();
              workbook.Write(ms);
              ms.Seek(0L, SeekOrigin.Begin);
              return ms;
          }
          
          public HSSFExcelResult(HSSFWorkbook workbook) : base(SaveWorkbook(workbook), ExcelMimeType)
          {
          }
          

          }

          [HttpGet]
          public ActionResult ExportSummaryToExcel(string startDate, string endDate, string postalCode)
          {
          HSSFWorkbook workbook = _summaryByAgeStagePostalCodeService.ExportSummaryToExcel(startDate, endDate, postalCode);
          return new HSSFExcelResult(workbook) { FileDownloadName = "Summary.xls" };
          }


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          F Offline
          F Offline
          Fokwa Divine
          wrote on last edited by
          #4

          We finally found the issue. This template file

          SummaryByAgeStagePostalBlank.xls

          was not getting copied along when we publish the project to our Test environment. We set the property for the file on Visual Studio to always copy if newer. The initial setting was "Do not copy".

          J 1 Reply Last reply
          0
          • F Fokwa Divine

            We finally found the issue. This template file

            SummaryByAgeStagePostalBlank.xls

            was not getting copied along when we publish the project to our Test environment. We set the property for the file on Visual Studio to always copy if newer. The initial setting was "Do not copy".

            J Offline
            J Offline
            jschell
            wrote on last edited by
            #5

            Your code needs better error detection. As already noted do not eat exceptions. Also do checks to make sure you actually did something. For example, did you read the file but it was empty?

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups