65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP MVC 以不同文件格式(CSV、Excel、PDF)导出/下载 Grid 内容

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2016年2月13日

CPOL

5分钟阅读

viewsIcon

28063

使用 ASP MVC 将 Grid 内容导出为不同文件格式(CSV、Excel、PDF)的多种方法

 源代码在此 

引言

在 Web 应用程序中,导出数据网格/表格内容是一项常见的需求。无论是作为 PDF 文档用于报告,还是作为 CSV 纯文本文件或 Excel 文档导出。但每个应用程序都有其独特的上下文和特定要求,这促使开发人员和设计人员不断重写现有资源或对其进行自定义。

在此,我想分享几种在 ASP .NET MVC 中导出 HTML Grid 内容的方法,并尝试使其通用且可重用。

背景

 最近我需要处理 Bootstrap 表格并将其内容导出为 CSV 和 PDF。我为此进行了搜索,找到了很多示例,但没有一个完全符合我的要求。我不得不定制它们或编写自己的代码。

我的需求很简单。我有一个 HTML 按钮,点击后表格内容将以指定的文件格式导出。在服务器端,我有一个数据列表,我想将其转换为请求的格式。

我的需求包括:

  • 最快的导出方法:即使我拥有大量数据,我也不会花费大部分时间进行数据转换。
  • 无 I/O 磁盘访问
  • 为下载文档指定文件名
  • 下载的文档将在 Excel 或 PDF 阅读器中打开

对此有不同的解决方案。每种解决方案都有其缺点。在这里,我想与您分享我的工作成果,并在之后讨论每种解决方案的不足之处。我提供了一个可以下载和测试的示例应用程序。这只是一个使用员工数据集的基本应用程序,该数据集显示在 Bootstrap 网格中,并配有几个导出内容的按钮。 

 下面的代码将包含:

csvFileResult 通用类及其如何用于导出到 CSV 文件

pdfFileResult 类及其如何用于导出到 PDF 文件

一个不同的 xslFileResult 用于导出到 Excel 文档。

 

 

使用代码

  1. 导出 Grid 到 CSV

这是一个 csvFileResult 类代码,它继承自 ASP.NET MVC 的 FileResult,并将数据集合转换为 CSV 文件格式。

 

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace MVCExport
{

    /// <summary>
    /// CSV file result impementation
    /// </summary>
    /// <typeparam name="TEntity">Entity list to transform to CSV</typeparam>
    public class CsvFileResult<TEntity> : FileResult where TEntity : class
    {
        #region Fields

        private const string DefaultContentType = "text/csv";
        private string _delimiter;
        private string _lineBreak;
        private Encoding _contentEncoding;
        private IEnumerable<string> _headers;
        private IEnumerable<PropertyInfo> _sourceProperties;
        private IEnumerable<TEntity> _dataSource;
        private Func<TEntity, IEnumerable<string>> _map;

        #endregion

        #region Properties

        public Func<TEntity, IEnumerable<string>> Map
        {
            get
            {

                return _map;
            }
            set { _map = value; }
        }
        public IEnumerable<TEntity> DataSource
        {
            get
            {
                return this._dataSource;
            }
        }
        /// <summary>
        /// CSV delimiter default ,
        /// </summary>
        public string Delimiter
        {
            get
            {
                if (string.IsNullOrEmpty(this._delimiter))
                {
                    this._delimiter = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
                }

                return this._delimiter;
            }

            set { this._delimiter = value; }
        }

        /// <summary>
        /// Content Encoding (default is UTF8).
        /// </summary>
        public Encoding ContentEncoding
        {

            get
            {
                if (this._contentEncoding == null)
                {
                    this._contentEncoding = Encoding.Unicode;
                }

                return this._contentEncoding;
            }

            set { this._contentEncoding = value; }


        }

        /// <summary>
        /// the first line of the CSV file, column headers
        /// </summary>
        public IEnumerable<string> Headers
        {
            get
            {
                if (this._headers == null)
                {
                    this._headers = typeof(TEntity).GetProperties().Select(x => x.Name);
                }

                return this._headers;
            }

            set { this._headers = value; }
        }

        public IEnumerable<PropertyInfo> SourceProperties
        {
            get
            {
                if (this._sourceProperties == null)
                {
                    this._sourceProperties = typeof(TEntity).GetProperties();
                }

                return this._sourceProperties;
            }
        }



        /// <summary>
        ///  byte order mark (BOM)  .
        /// </summary>
        public bool HasPreamble { get; set; }

        /// <summary>
        /// Line  delimiter \n
        /// </summary>
        public string LineBreak
        {
            get
            {
                if (string.IsNullOrEmpty(this._lineBreak))
                {
                    this._lineBreak = Environment.NewLine;
                }

                return this._lineBreak;
            }

            set { this._lineBreak = value; }
        }



        /// <summary>
        /// Get or Set the response output buffer 
        /// </summary>
        public bool BufferOutput { get; set; }

        #endregion

        #region Ctor
        /// <summary>
        /// Creats new instance of CsvFileResult{TEntity}
        /// </summary>
        /// <param name="source">List of data to be transformed to csv</param>
        /// <param name="fileDonwloadName">CSV file name</param>
        /// <param name="contentType">Http response content type</param>
        public CsvFileResult(IEnumerable<TEntity> source, string fileDonwloadName, string contentType)
            : base(contentType)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            this._dataSource = source;

            if (string.IsNullOrEmpty(fileDonwloadName))
                throw new ArgumentNullException("fileDonwloadName");
            this.FileDownloadName = fileDonwloadName;

            this.BufferOutput = true;

        }

        /// <summary>
        /// Creats new instance of CsvFileResult{TEntity}
        /// </summary>
        /// <param name="source">List of data to be transformed to csv</param>
        /// <param name="fileDonwloadName">CSV file name</param>
        public CsvFileResult(IEnumerable<TEntity> source, string fileDonwloadName)
            : this(source, fileDonwloadName, DefaultContentType)
        {

        }

        /// <summary>
        /// Creats new instance of CsvFileResult{TEntity}
        /// </summary>
        /// <param name="source">List of data to be transformed to csv</param>
        /// <param name="fileDonwloadName">CSV file name</param>
        /// <param name="map">Custom transformation delegate</param>
        /// <param name="headers">Columns headers</param>
        public CsvFileResult(IEnumerable<TEntity> source, string fileDonwloadName, Func<TEntity, IEnumerable<string>> map, IEnumerable<string> headers)
            : this(source, fileDonwloadName, DefaultContentType)
        {
            this._headers = headers;
            this._map = map;
        }

        #endregion

        #region override

        protected override void WriteFile(HttpResponseBase response)
        {
            response.ContentEncoding = this.ContentEncoding;
            response.BufferOutput = this.BufferOutput;
            var streambuffer = ContentEncoding.GetBytes(this.GetCSVData());
            if (HasPreamble)
            {
                var preamble = this.ContentEncoding.GetPreamble();
                response.OutputStream.Write(preamble, 0, preamble.Length);
            }

            response.OutputStream.Write(streambuffer, 0, streambuffer.Length);
        }

        #endregion

        #region local routines

        private string GetCSVHeader()
        {
            string csv = "";
            csv = String.Join(this.Delimiter, this.Headers.Select(x => this.FormatCSV(x)));

            return csv;
        }


        private string GetCSVData()
        {
            string csv = GetCSVHeader();
            Func<TEntity, string> expr = x => this.Map == null ? this.FormatPropertiesCSV(x) : this.FormatMapCSV(x);
            csv += this.LineBreak + String.Join(this.LineBreak, this.DataSource.Select(expr));
            return csv;
        }

        private string FormatCSV(string str)
        {
            str = (str ?? "").Replace(this.Delimiter, "\"" + this.Delimiter + "\"");
            str = str.Replace(this.LineBreak, "\"" + this.LineBreak + "\"");
            str = str.Replace("\"", "\"\"");

            return String.Format("\"{0}\"", str);
        }

        private string FormatPropertiesCSV(TEntity obj)
        {
            string csv = "";

            foreach (var pi in this.SourceProperties)
            {
                string val = GetPropertyValue(pi, obj);
                csv += FormatCSV(val) + this.Delimiter;
            }

            csv = csv.TrimEnd(this.Delimiter.ToCharArray());
            return csv;
        }


        private string GetPropertyValue(PropertyInfo pi, object source)
        {
            try
            {
                var result = pi.GetValue(source, null);
                return (result == null) ? "" : result.ToString();
            }
            catch (Exception)
            {
                return "Can not obtain the value";
            }
        }

        private string FormatMapCSV(TEntity obj)
        {
            return String.Join(this.Delimiter, this.Map(obj).Select(x => FormatCSV(x)));
        }


        #endregion

    }
}

如何使用它

CsvFileResult 定义了用于行中断、分隔符、编码、文件名、数据源、标题列以及如何将数据源转换为特定 CSV 数据格式的映射的各种属性。还有两个构造函数用于初始化这些属性。

以下是一些在控制器操作中使用 CsvFileResult 的示例:

 public ActionResult MyExportCSV()
        {
            IEnumerable<Employee> dataList = _dataSource.GetAll();
            return new CsvFileResult<Employee>(dataList, "toto.csv");
        }

在此示例中,我们将数据列表获取为 Employee 的 IEnumerable,然后调用 CsvFileResult 将其转换为 CSV,并指定文件名(此处为 toto.csv)和数据源(即数据列表)。

在这里,CSV 标题将是 Employee 类的所有属性名,行将是数据列表中每个项的值。

让我们看另一个示例:

 

 public ActionResult MyCustomExportCSV()
        {

            IEnumerable<string> headers = new[] { 
                "FullName" , 
                "Title" ,
                "PhoneNumber" ,
                "Address" 
            };

            IEnumerable<Employee> dataList = _dataSource.GetAll();
            Func<Employee, IEnumerable<string>> map = x => new[] { x.TitleOfCourtesy + " " + x.LastName + " " + x.FirstName, x.Title, x.HomePhone, x.Address + ", " + x.PostalCode + "  " + x.City + "  " + x.Region };
            return new CsvFileResult<Employee>(dataList, "employees.csv", map, headers);
        }

在这里,我们指定了要导出为标题的列,并通过进行特殊映射来转换数据列表。

    2. 导出到 PDF

 使用已知的库 iTextSharp 将 Razor 视图转换为 PDF。因此,我们首先创建一个用于显示 Grid 的 Razor 视图,并用数据源填充它,然后通过 PdfFileResult 将结果转换为 PDF。

这是 PdfFileResult 的代码

using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace MVCExport
{
    public class PdfFileResult<TEntity> : FileResult where TEntity : class
    {
        #region Fields

        private const string DefaultContentType = "application/pdf";
        private Encoding _contentEncoding;
        private object _viewModel;
        private ControllerContext _context;
        private string _viewName;

        #endregion

        #region Properties

        /// <summary>
        /// 
        /// </summary>
        public string ViewName
        {
            get { return _viewName; }
            set { _viewName = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public ControllerContext Context
        {
            get { return _context; }
            set { _context = value; }
        }

        

        /// <summary>
        /// Data list to be transformed to Excel
        /// </summary>
        public object ViewModel
        {
            get
            {
                return this._viewModel;
            }
             set { _viewModel = value; }
        }
        
        /// <summary>
        /// Content Encoding (default is UTF8).
        /// </summary>
        public Encoding ContentEncoding
        {

            get
            {
                if (this._contentEncoding == null)
                {
                    this._contentEncoding = Encoding.UTF8;
                }

                return this._contentEncoding;
            }

            set { this._contentEncoding = value; }


        }

        /// <summary>
        ///  byte order mark (BOM)  .
        /// </summary>
        public bool HasPreamble { get; set; }

        /// <summary>
        /// Get or Set the response output buffer 
        /// </summary>
        public bool BufferOutput { get; set; }

        #endregion

        #region Ctor
         /// <summary>
         /// 
         /// </summary>
         /// <param name="vieModel"></param>
         /// <param name="context"></param>
         /// <param name="viewName"></param>
         /// <param name="fileDonwloadName"></param>
         /// <param name="contentType"></param>
        public PdfFileResult(object viewModel, ControllerContext context, string viewName, string fileDonwloadName, string contentType)
            : base(contentType)
        {
            if (viewModel == null)
                throw new ArgumentNullException("viewModel");
            this._viewModel = viewModel;

            if (string.IsNullOrEmpty(fileDonwloadName))
                throw new ArgumentNullException("fileDonwloadName");
            this.FileDownloadName = fileDonwloadName;

            if (string.IsNullOrEmpty(viewName))
                throw new ArgumentNullException("viewName");
            this._viewName = viewName;

            if (context==null)
                throw new ArgumentNullException("context");
            this._context = context;
            this.BufferOutput = true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="viewModel"></param>
        /// <param name="context"></param>
        /// <param name="viewName"></param>
        /// <param name="fileDonwloadName"></param>
        public PdfFileResult(object viewModel, ControllerContext context, string viewName, string fileDonwloadName)
            : this(viewModel, context, viewName, fileDonwloadName,DefaultContentType)
        {

        }
        
        #endregion

        protected override void WriteFile(HttpResponseBase response)
        {
            response.ContentEncoding = this.ContentEncoding;
            response.BufferOutput = this.BufferOutput;
           
            if (HasPreamble)
            {
                var preamble = this.ContentEncoding.GetPreamble();
                response.OutputStream.Write(preamble, 0, preamble.Length);
            }

            this.RenderPDFView(response);
        }

        private void RenderPDFView(HttpResponseBase response)
        {
            string htmlView = this.RenderViewToString(this.Context, this.ViewName, this.ViewModel);
            byte[] streambuffer;
            using (var document = new Document())
            {
                using (var workStream = new MemoryStream())
                {
                    PdfWriter writer = PdfWriter.GetInstance(document, workStream);
                    writer.CloseStream = false;
                    document.Open();
                    using (var reader = new StringReader(htmlView))
                    {
                        XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader);
                        document.Close();
                        streambuffer = workStream.ToArray() ;
                        response.OutputStream.Write(streambuffer, 0, streambuffer.Length);
                    }
                }
            }
        }

        private string RenderViewToString(ControllerContext context, String viewPath, object model = null)
        {
            context.Controller.ViewData.Model = model;
            using (var sw = new StringWriter())
            {
                var viewResult = ViewEngines.Engines.FindView(context, viewPath, null);
                var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw);
                viewResult.View.Render(viewContext, sw);
                viewResult.ViewEngine.ReleaseView(context, viewResult.View);
                return sw.GetStringBuilder().ToString();
            }
        }
    }
}

如何使用它

首先,让我们创建一个用于在 PDF 中显示 Grid 的 Razor 视图

 
@model MVCExport.Models.EmployeeListViewModel
@{
    Layout = null;
}

<html>
<head>
    <title> Employees </title>
    <style>
        thead th{
            background:red;
            color:white
        }
        caption{
           background:blue;
            color:white;
            font-weight:bold
        }
    </style> 
</head>
<body>
    <table>
        <caption>
             Employees 
        </caption>
        <thead valign="top" >
            <tr>
                @foreach (var head in @Model.Headers)
                {
                    <th >@head</th>
                }
            </tr>
        </thead>
        <tbody>
            @foreach (var items in @Model.Data)
            {
               <tr> 
              @foreach (var item in @items)
              {
                <th>@item</th>
              }
               </tr>
            }
        </tbody>
        <tfoot>
            <tr>
                <td colspan="4" align="right"><strong> Total : </strong>@Model.Total</td>
            </tr>
        </tfoot>
    </table>
</body>
</html>

现在,在任何控制器操作中,让我们创建一个导出操作

 

 public ActionResult PdfExport()
 {
            IEnumerable<string> headers = new[] { 
                "FullName" , 
                "Title" ,
                "PhoneNumber" ,
                "Address" 
            };

            IEnumerable<Employee> dataList = _dataSource.GetAll();
      Func<Employee, IEnumerable<string>> map = x => new[] { x.TitleOfCourtesy + " " + x.LastName + " " + x.FirstName, x.Title, x.HomePhone, x.Address + ", " + x.PostalCode + "  " + x.City + "  " + x.Region };
            EmployeeListViewModel vm = new EmployeeListViewModel()
            {
                Total = dataList.Count(),
                Headers = headers,
                Data = dataList.Select(x => map(x))
            };

       return new PdfFileResult<Employee>(vm, this.ControllerContext, @"PDFGridExport", "employees.pdf");
}

在此示例中,通过传递 EmployeeListViewModel 作为数据源、controllerContext 来编译 Razor 视图、Razor 视图名称(此处为 PDFGridExport,对应 PDFGridExport.cshtml)以及最终的导出文件名 employees.pdf 来调用 PdfFileResult。

3. 导出到 Excel

 在附带的源代码中,您可以找到三种使用 Ole 连接、ASP GridView 和 Razor 视图将 Grid 视图导出为 Excel 文档的方法。我们还可以使用 MS Office 中的本机 Excel 库或使用 OpenXML 库来生成 Xlsx 文档,但这些方法超出了本示例的范围。

让我们来看看第一种使用 Ole 连接的方法。我喜欢这种方法,但与其他方法相比,它速度较慢。

这是 XslFileResult 类的代码: 

using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;

namespace MVCExport
{
    public class XlsFileResult<TEntity> : FileResult where TEntity : class
    {
        #region Fields

        private const string DefaultContentType = "application/vnd.ms-excel";
        private string _tempPath;
        private string _tableName;



        private Encoding _contentEncoding;
        private IEnumerable<string> _headers;
        private IEnumerable<PropertyInfo> _sourceProperties;
        private IEnumerable<TEntity> _dataSource;
        private Func<TEntity, IEnumerable<string>> _map;

        #endregion

        #region Properties

        public string TableName
        {
            get
            {

                if (string.IsNullOrEmpty(_tableName))
                {
                    _tableName = typeof(TEntity).Name;
                }

                _tableName = _tableName.Trim().Replace(" ", "_");
                if (_tableName.Length > 30)
                {
                    _tableName = _tableName.Substring(0, 30);
                }

                return _tableName;
            }
            set { _tableName = value; }
        }

        public string TempPath
        {
            get
            {
                if (string.IsNullOrEmpty(_tempPath))
                {
                    _tempPath = HostingEnvironment.MapPath(Path.Combine(@"~/App_Data", this.FileDownloadName));
                }
                return _tempPath;
            }
            set
            {
                _tempPath = Path.Combine(value, this.FileDownloadName);
            }
        }

        /// <summary>
        /// Custom properties transformation
        /// </summary>
        public Func<TEntity, IEnumerable<string>> Map
        {
            get
            {
                return _map;
            }

            set { _map = value; }
        }

        /// <summary>
        /// Data list to be transformed to Excel
        /// </summary>
        public IEnumerable<TEntity> DataSource
        {
            get
            {
                return this._dataSource;
            }
        }

        /// <summary>
        /// Content Encoding (default is UTF8).
        /// </summary>
        public Encoding ContentEncoding
        {

            get
            {
                if (this._contentEncoding == null)
                {
                    this._contentEncoding = Encoding.UTF8;
                }

                return this._contentEncoding;
            }

            set { this._contentEncoding = value; }


        }

        /// <summary>
        /// the first line of the CSV file, column headers
        /// </summary>
        public IEnumerable<string> Headers
        {
            get
            {
                if (this._headers == null)
                {
                    this._headers = typeof(TEntity).GetProperties().Select(x => x.Name);
                }

                return this._headers;
            }

            set { this._headers = value; }
        }

        /// <summary>
        /// Object's properties to convert to excel  
        /// </summary>
        public IEnumerable<PropertyInfo> SourceProperties
        {
            get
            {
                if (this._sourceProperties == null)
                {
                    this._sourceProperties = typeof(TEntity).GetProperties();
                }

                return this._sourceProperties;
            }
        }

        /// <summary>
        ///  byte order mark (BOM)  .
        /// </summary>
        public bool HasPreamble { get; set; }

        /// <summary>
        /// Get or Set the response output buffer 
        /// </summary>
        public bool BufferOutput { get; set; }

        #endregion

        #region Ctor
        /// <summary>
        /// Creats new instance of CsvFileResult{TEntity}
        /// </summary>
        /// <param name="source">List of data to be transformed to csv</param>
        /// <param name="fileDonwloadName">CSV file name</param>
        /// <param name="contentType">Http response content type</param>
        public XlsFileResult(IEnumerable<TEntity> source, string fileDonwloadName, string contentType)
            : base(contentType)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            this._dataSource = source;

            if (string.IsNullOrEmpty(fileDonwloadName))
                throw new ArgumentNullException("fileDonwloadName");
            this.FileDownloadName = fileDonwloadName;

            this.BufferOutput = true;
        }

        /// <summary>
        /// Creats new instance of CsvFileResult{TEntity}
        /// </summary>
        /// <param name="source">List of data to be transformed to csv</param>
        /// <param name="fileDonwloadName">CSV file name</param>
        public XlsFileResult(IEnumerable<TEntity> source, string fileDonwloadName)
            : this(source, fileDonwloadName, DefaultContentType)
        {

        }

        /// <summary>
        /// Creats new instance of CsvFileResult{TEntity}
        /// </summary>
        /// <param name="source">List of data to be transformed to csv</param>
        /// <param name="fileDonwloadName">CSV file name</param>
        /// <param name="map">Custom transformation delegate</param>
        /// <param name="headers">Columns headers</param>
        public XlsFileResult(IEnumerable<TEntity> source, Func<TEntity, IEnumerable<string>> map, IEnumerable<string> headers, string fileDonwloadName)
            : this(source, fileDonwloadName, DefaultContentType)
        {
            this._headers = headers;
            this._map = map;
        }

        #endregion

        protected override void WriteFile(HttpResponseBase response)
        {
            response.ContentEncoding = this.ContentEncoding;
            response.BufferOutput = this.BufferOutput;

            if (HasPreamble)
            {
                var preamble = this.ContentEncoding.GetPreamble();
                response.OutputStream.Write(preamble, 0, preamble.Length);
            }

            this.RenderResponse(response);
        }

        private void RenderResponse(HttpResponseBase response)
        {
            if (File.Exists(this.TempPath))
            {
                File.Delete(this.TempPath);
            }
            string sexcelconnectionstring = GetConnectionString(this.TempPath);
            using (System.Data.OleDb.OleDbConnection oledbconn = new System.Data.OleDb.OleDbConnection(sexcelconnectionstring))
            {
                oledbconn.Open();
                this.createTable(oledbconn);
                this.InsertData(oledbconn);
            }

            var streambuffer = this.ContentEncoding.GetBytes(File.ReadAllText(this.TempPath));

            response.OutputStream.Write(streambuffer, 0, streambuffer.Length);
        }

        private IEnumerable<string> GetEntityValues(TEntity obj)
        {
            IEnumerable<string> ds = null;
            if (this.Map != null)
            {
                ds = this.Map(obj);
            }
            else
            {
                ds = this.SourceProperties.Select(x => this.GetPropertyValue(x, obj));

            }

            return ds;
        }

        private string GetPropertyValue(PropertyInfo pi, object source)
        {
            try
            {
                var result = pi.GetValue(source, null);
                return (result == null) ? "" : result.ToString();
            }
            catch (Exception)
            {
                return "Can not obtain the value";
            }
        }

        private string GetConnectionString(string FileName, bool hasHeaders = true)
        {
            string HDR = hasHeaders ? "Yes" : "No";
            return Path.GetExtension(FileName).Equals(".xlsx") ?
                "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FileName + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=0\"" :
                "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FileName + ";Extended Properties=\"Excel 8.0;HDR=" + HDR + ";IMEX=0\"";
        }

        private void createTable(OleDbConnection con)
        {
            string tyed = string.Join(",", this.Headers.Select(x => x + " " + "VARCHAR"));
            string commandText = string.Format("CREATE TABLE [{0}]({1});", this.TableName, tyed);
            OleDbCommand oledbcmd = new OleDbCommand(commandText,con);
            oledbcmd.ExecuteNonQuery();
        }

        private void InsertData(OleDbConnection con)
        {
            OleDbDataAdapter oleAdap = new OleDbDataAdapter("SELECT * FROM [" + this.TableName + "]", con);
            OleDbCommandBuilder oleCmdBuilder = new OleDbCommandBuilder(oleAdap);
            oleCmdBuilder.QuotePrefix = "[";
            oleCmdBuilder.QuoteSuffix = "]";
            OleDbCommand cmd = oleCmdBuilder.GetInsertCommand();
            foreach (TEntity row in this.DataSource)
            {
                var pVals = GetEntityValues(row);
                int index = 0;
                foreach (OleDbParameter param in cmd.Parameters)
                {
                    param.Value = pVals.ElementAt(index);
                    index++;
                }

                cmd.ExecuteNonQuery();
            }
        }

        private void InsertDataQuery(OleDbConnection cn)
        {
            StringBuilder sbSql = new StringBuilder();
            sbSql.Length = 0;
            sbSql.Insert(0, "INSERT INTO [" + this.TableName + "]");
            sbSql.Append(" (");
            sbSql.Append(string.Join(",", this.Headers));
            sbSql.Append(")");
            sbSql.Append(string.Join(" UNION ALL ", this.DataSource.Select(x => "  SELECT  " + string.Join(",", GetEntityValues(x)) + " ")));
            sbSql.Append(";");
            OleDbCommand cmd = new OleDbCommand(sbSql.ToString(), cn);
            cmd.ExecuteNonQuery();
        }
    }
}

如何使用它

一个在控制器操作中使用 XslFileResult 的示例

public ActionResult ExcelExport()
        {
            IEnumerable<Employee> dataList = _dataSource.GetAll();
             

            return new XlsFileResult<Employee>(dataList, "employees.xls");
        }

只需获取一个数据列表并将其传递给 XslFileResult,然后指定文件名(此处为 employees.xls)。

在附带的源代码中,您可以找到其他导出为 Excel 文档的示例,包括使用 RDLC 报表。

讨论

将 Grid/表格导出到 CSV 是最简单、最快捷的方法。当不需要导出为本机 Excel 格式时,可以使用 CSV,因为您可以在 MS Excel 和许多其他电子表格应用程序中打开它,也可以将其作为纯文本文件处理。

使用 Razor 视图和 iTextSharp 导出到 PDF 非常出色,您可以生成样式精美的报表。

当导出到本机 Excel 文档时,您可以选择使用本机 Office 库或 OpenXML 来处理 Xslx,或者使用 OleDb 连接将电子表格填充为数据表。最后,您也可以直接在文档中使用 HTML 表格。

最后,您可以使用 RDLC 报表导出到所有文件格式。

 有趣的点

这里有一个可重用的代码,您在处理导出数据网格时可以直接将其包含在您的应用程序中。您也可以将附带的源代码用于学习目的。 

 

 

 

© . All rights reserved.