【问题标题】:C# Export to Excel from classC# 从类导出到 Excel
【发布时间】:2019-01-15 23:16:31
【问题描述】:

我正在按照以下示例将数据从表/存储过程导出到 Excel。 https://www.c-sharpcorner.com/UploadFile/rahul4_saxena/how-to-export-multiple-data-tables-to-multiple-worksheets-in/

唯一的区别是,因为我有一个 Angular/MVC 项目,所以我在课堂上使用了这段代码。在方法“Export_To_Excel()”中,有 响应。清除();和其他响应方法。但我收到错误消息,“当前上下文中不存在响应。”所以我尝试更改为完全合格的参考: HttpContext.Current.Response 或 System.Web.HttpContext.Current.Response 但现在我得到错误,“对象引用未设置为对象的实例”

请指导怎么办?这是我在cs文件中的完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ClosedXML.Excel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MyProject.DAL
{
    public class CreateWorkBook
    {
        private DataTable getAllEmployeesList()
        {

            using (SqlConnection con = Connection.GetConnection())
            {
                using (SqlCommand cmd = new SqlCommand(@"SELECT * FROM Employee ORDER BY ID;"))
                {
                    using (SqlDataAdapter da = new SqlDataAdapter())
                    {
                        DataTable dt = new DataTable();
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = con;
                        da.SelectCommand = cmd;
                        da.Fill(dt);
                        return dt;
                    }
                }
            }
        }

        private DataTable getAllEmployeesOrderList()
        {

            using (SqlConnection con = Connection.GetConnection())
            {
                using (SqlCommand cmd = new SqlCommand("SELECT * FROM OrderDetails ORDER BY Order_ID;"))
                {
                    using (SqlDataAdapter da = new SqlDataAdapter())
                    {
                        DataTable dt = new DataTable();
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = con;
                        da.SelectCommand = cmd;
                        da.Fill(dt);
                        return dt;
                    }
                }
            }
        }

        public DataSet getDataSetExportToExcel()
        {
            DataSet ds = new DataSet();
            DataTable dtEmp = new DataTable("Employee");
            dtEmp = getAllEmployeesList();

            DataTable dtEmpOrder = new DataTable("Order List");
            dtEmpOrder = getAllEmployeesOrderList();
            ds.Tables.Add(dtEmp);
            ds.Tables.Add(dtEmpOrder);
            return ds;
        }
        public string SetToExport(string channel, string assets )
        {
            string status = Export_To_Excel();
            return "success";
        }
        protected string Export_To_Excel()
        {
            try
            {
                DataSet ds = getDataSetExportToExcel();
                using (XLWorkbook wb = new XLWorkbook())
                {
                    wb.Worksheets.Add(ds);
                    wb.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
                    wb.Style.Font.Bold = true;
// Error here – 
//An object reference not set to an instance of Object  
                    HttpContext.Current.Response.Clear();
                    HttpContext.Current.Response.Buffer = true;
                    System.Web.HttpContext.Current.Response.Charset = "";
                    System.Web.HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                    System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename= SubmissionForm.xlsx");
                    using (MemoryStream MyMemoryStream = new MemoryStream())
                    {
                        wb.SaveAs(MyMemoryStream);
                        MyMemoryStream.WriteTo(System.Web.HttpContext.Current.Response.OutputStream);
                        System.Web.HttpContext.Current.Response.Flush();
                        System.Web.HttpContext.Current.Response.End();
                    }
                }

                return "success";
            }
            catch (Exception e)
            {
                throw e;
                //return "Export to Excel failed";
            }

        }

        }
}

【问题讨论】:

  • Response 只会在网络请求的上下文中填充,你是如何调用你的代码的?
  • 我会把它分成几个步骤。创建 Excel 的部分应该只返回一个表示文件内容的字节数组。它不应该关心文件的去向——流式传输到 Web 客户端、保存到文件等。您的网页调用该代码,获取字节数组,并将其流式传输到客户端。

标签: c# excel reference httpcontext system.web


【解决方案1】:

正如@Scott 在 cmets 中提到的,您应该将其分解为更小的问题。

  1. 首先创建代码以成功生成excel文件。这应该返回一个byte[]。为了简化事情,您可以创建一个控制台应用程序,将文件本地保存到 PC 开始,对其进行测试并确保其正常工作。
  2. 在第 1 部分开始工作后,将生成 byte[] 的代码复制到您的 Web 项目中。然后你只需要弄清楚如何将 MVC 中的文件下载到客户端。

下面的代码可能会有所帮助。

    // CreateWorkBook class
    public byte[] Export_To_Excel()
    {           
        DataSet ds = getDataSetExportToExcel();
        using (XLWorkbook wb = new XLWorkbook())
        {
            wb.Worksheets.Add(ds);
            wb.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
            wb.Style.Font.Bold = true;

            using (MemoryStream myMemoryStream = new MemoryStream())
            {
                wb.SaveAs(myMemoryStream);

                // return memory stream as byte array
                return myMemoryStream.ToArray();
            }
        }
    }

然后在您的控制器中,您可以使用FileResult 返回 excel 文件。下面是一个如何在 MVC 控制器中完成它的示例。

// your MVC controller
[HttpGet]
public FileResult DownloadExcel()
{
    var createExcel = new CreateWorkBook();
    byte[] excelFile = null;
    try
    {
        excelFile = createExcel.Export_To_Excel();
    }
    catch (Exception ex)
    {
        // handle exception
    }
    string fileType = @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    string fileName = "excel.xlsx";

    return File(excelFile, fileType, fileName);
}

【讨论】:

    【解决方案2】:

    请不要使用下面与 Excel 导出操作无关的注释代码。

    //HttpContext.Current.Response.Clear();
    //HttpContext.Current.Response.Buffer = true;
    //System.Web.HttpContext.Current.Response.Charset = "";
    //System.Web.HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    //System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename= SubmissionForm.xlsx");
    
    using (MemoryStream MyMemoryStream = new MemoryStream())
    {
        wb.SaveAs(MyMemoryStream);
        //you need to replace below line according to your need. **
        //MyMemoryStream.WriteTo(System.Web.HttpContext.Current.Response.OutputStream);
        //System.Web.HttpContext.Current.Response.Flush();
        //System.Web.HttpContext.Current.Response.End();
    }
    

    ** 在不知道您的项目结构和您的意图的情况下,不可能告诉您下载/保存此文件的正确方法。

    【讨论】:

    • 我有 Angular6/MVC 项目。我需要根据用户选择调用一些 sql,并在单独的选项卡中使用来自每个数据集的数据创建 excel 工作簿。可以给点建议吗?
    • 您可以使用 api 端点返回 byte[]。你在使用 ApiConrollers 吗?
    • 不,我有 MVC 控制器。不知道 ApiConrollers。它有什么帮助?
    猜你喜欢
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多