C#封装一个快速读取写入操作excel的工具类

 更新时间:2024年01月29日 16:49:14   作者:搬砖的诗人Z  
这篇文章主要为大家详细介绍了C#如何封装一个快速读取写入操作excel的工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

这里封装了3个实用类ExcelDataReaderExtensions,ExcelDataSetConfiguration,ExcelDataTableConfiguration和一个实用代码参考: 

using ExcelDataReader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExeclHelper
{
    /// <summary>
    /// Processing configuration options and callbacks for AsDataTable().
    /// </summary>
    public class ExcelDataTableConfiguration
    {
        /// <summary>
        /// Gets or sets a value indicating the prefix of generated column names.
        /// </summary>
        public string EmptyColumnNamePrefix { get; set; } = "Column";

        /// <summary>
        /// Gets or sets a value indicating whether to use a row from the data as column names.
        /// </summary>
        public bool UseHeaderRow { get; set; } = false;

        /// <summary>
        /// Gets or sets a callback to determine which row is the header row. Only called when UseHeaderRow = true.
        /// </summary>
        public Action<IExcelDataReader> ReadHeaderRow { get; set; }

        /// <summary>
        /// Gets or sets a callback to determine whether to include the current row in the DataTable.
        /// </summary>
        public Func<IExcelDataReader, bool> FilterRow { get; set; }

        /// <summary>
        /// Gets or sets a callback to determine whether to include the specific column in the DataTable. Called once per column after reading the headers.
        /// </summary>
        public Func<IExcelDataReader, int, bool> FilterColumn { get; set; }
    }
}
using ExcelDataReader;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExeclHelper
{
    /// <summary>
    /// ExcelDataReader DataSet extensions
    /// </summary>
    public static class ExcelDataReaderExtensions
    {
        /// <summary>
        /// Converts all sheets to a DataSet
        /// </summary>
        /// <param name="self">The IExcelDataReader instance</param>
        /// <param name="configuration">An optional configuration object to modify the behavior of the conversion</param>
        /// <returns>A dataset with all workbook contents</returns>
        public static DataSet AsDataSet(this IExcelDataReader self, ExcelDataSetConfiguration configuration = null)
        {
            if (configuration == null)
            {
                configuration = new ExcelDataSetConfiguration();
            }

            self.Reset();

            var tableIndex = -1;
            var result = new DataSet();
            do
            {
                tableIndex++;
                if (configuration.FilterSheet != null && !configuration.FilterSheet(self, tableIndex))
                {
                    continue;
                }

                var tableConfiguration = configuration.ConfigureDataTable != null
                    ? configuration.ConfigureDataTable(self)
                    : null;

                if (tableConfiguration == null)
                {
                    tableConfiguration = new ExcelDataTableConfiguration();
                }

                var table = AsDataTable(self, tableConfiguration);
                result.Tables.Add(table);
            }
            while (self.NextResult());

            result.AcceptChanges();

            if (configuration.UseColumnDataType)
            {
                FixDataTypes(result);
            }

            self.Reset();

            return result;
        }

        private static string GetUniqueColumnName(DataTable table, string name)
        {
            var columnName = name;
            var i = 1;
            while (table.Columns[columnName] != null)
            {
                columnName = string.Format("{0}_{1}", name, i);
                i++;
            }

            return columnName;
        }

        private static DataTable AsDataTable(IExcelDataReader self, ExcelDataTableConfiguration configuration)
        {
            var result = new DataTable { TableName = self.Name };
            result.ExtendedProperties.Add("visiblestate", self.VisibleState);
            var first = true;
            var emptyRows = 0;
            var columnIndices = new List<int>();
            while (self.Read())
            {
                if (first)
                {
                    if (configuration.UseHeaderRow && configuration.ReadHeaderRow != null)
                    {
                        configuration.ReadHeaderRow(self);
                    }

                    for (var i = 0; i < self.FieldCount; i++)
                    {
                        if (configuration.FilterColumn != null && !configuration.FilterColumn(self, i))
                        {
                            continue;
                        }

                        var name = configuration.UseHeaderRow
                            ? Convert.ToString(self.GetValue(i))
                            : null;

                        if (string.IsNullOrEmpty(name))
                        {
                            name = configuration.EmptyColumnNamePrefix + i;
                        }

                        // if a column already exists with the name append _i to the duplicates
                        var columnName = GetUniqueColumnName(result, name);
                        var column = new DataColumn(columnName, typeof(object)) { Caption = name };
                        result.Columns.Add(column);
                        columnIndices.Add(i);
                    }

                    result.BeginLoadData();
                    first = false;

                    if (configuration.UseHeaderRow)
                    {
                        continue;
                    }
                }

                if (configuration.FilterRow != null && !configuration.FilterRow(self))
                {
                    continue;
                }

                if (IsEmptyRow(self))
                {
                    emptyRows++;
                    continue;
                }

                for (var i = 0; i < emptyRows; i++)
                {
                    result.Rows.Add(result.NewRow());
                }

                emptyRows = 0;

                var row = result.NewRow();

                for (var i = 0; i < columnIndices.Count; i++)
                {
                    var columnIndex = columnIndices[i];
                    var value = self.GetValue(columnIndex);
                    row[i] = value;
                }

                result.Rows.Add(row);
            }

            result.EndLoadData();
            return result;
        }

        private static bool IsEmptyRow(IExcelDataReader reader)
        {
            for (var i = 0; i < reader.FieldCount; i++)
            {
                if (reader.GetValue(i) != null)
                    return false;
            }

            return true;
        }

        private static void FixDataTypes(DataSet dataset)
        {
            var tables = new List<DataTable>(dataset.Tables.Count);
            bool convert = false;
            foreach (DataTable table in dataset.Tables)
            {
                if (table.Rows.Count == 0)
                {
                    tables.Add(table);
                    continue;
                }

                DataTable newTable = null;
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    Type type = null;
                    foreach (DataRow row in table.Rows)
                    {
                        if (row.IsNull(i))
                            continue;
                        var curType = row[i].GetType();
                        if (curType != type)
                        {
                            if (type == null)
                            {
                                type = curType;
                            }
                            else
                            {
                                type = null;
                                break;
                            }
                        }
                    }

                    if (type == null)
                        continue;
                    convert = true;
                    if (newTable == null)
                        newTable = table.Clone();
                    newTable.Columns[i].DataType = type;
                }

                if (newTable != null)
                {
                    newTable.BeginLoadData();
                    foreach (DataRow row in table.Rows)
                    {
                        newTable.ImportRow(row);
                    }

                    newTable.EndLoadData();
                    tables.Add(newTable);
                }
                else
                {
                    tables.Add(table);
                }
            }

            if (convert)
            {
                dataset.Tables.Clear();
                dataset.Tables.AddRange(tables.ToArray());
            }
        }
    }
}
using ExcelDataReader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExeclHelper
{
    /// <summary>
    /// Processing configuration options and callbacks for IExcelDataReader.AsDataSet().
    /// </summary>
    public class ExcelDataSetConfiguration
    {
        /// <summary>
        /// Gets or sets a value indicating whether to set the DataColumn.DataType property in a second pass.
        /// </summary>
        public bool UseColumnDataType { get; set; } = true;

        /// <summary>
        /// Gets or sets a callback to obtain configuration options for a DataTable. 
        /// </summary>
        public Func<IExcelDataReader, ExcelDataTableConfiguration> ConfigureDataTable { get; set; }

        /// <summary>
        /// Gets or sets a callback to determine whether to include the current sheet in the DataSet. Called once per sheet before ConfigureDataTable.
        /// </summary>
        public Func<IExcelDataReader, int, bool> FilterSheet { get; set; }
    }
}

运用实例:

  private IList<string> GetTablenames(DataTableCollection tables)
  {
      var tableList = new List<string>();
      foreach (var table in tables)
      {
          tableList.Add(table.ToString());
      }

      return tableList;
  }

  public void ExportExcel()
  {
      try
      {
          //创建一个工作簿
          IWorkbook workbook = new HSSFWorkbook();

          //创建一个 sheet 表
          ISheet sheet = workbook.CreateSheet("合并数据");

          //创建一行
          IRow rowH = sheet.CreateRow(0);

          //创建一个单元格
          ICell cell = null;

          //创建单元格样式
          ICellStyle cellStyle = workbook.CreateCellStyle();

          //创建格式
          IDataFormat dataFormat = workbook.CreateDataFormat();

          //设置为文本格式,也可以为 text,即 dataFormat.GetFormat("text");
          cellStyle.DataFormat = dataFormat.GetFormat("@");

          //设置列名
          //foreach (DataColumn col in dt.Columns)
          //{
          //    //创建单元格并设置单元格内容
          //    rowH.CreateCell(col.Ordinal).SetCellValue(col.Caption);

          //    //设置单元格格式
          //    rowH.Cells[col.Ordinal].CellStyle = cellStyle;
          //}
          for (int i = 0; i < Headers.Count(); i++)
          {
              rowH.CreateCell(i).SetCellValue(Headers[i]);
              rowH.Cells[i].CellStyle = cellStyle;
          }

          //写入数据
          for (int i = 0; i < dataModels.Count; i++)
          {
              //跳过第一行,第一行为列名
              IRow row = sheet.CreateRow(i + 1);

              for (int j = 0; j < 11; j++)
              {
                  cell = row.CreateCell(j);
                  if (j == 0)
                      cell.SetCellValue(dataModels[i].title1.ToString());
                  if (j == 1)
                      cell.SetCellValue(dataModels[i].title2.ToString());
                  if (j == 2)
                      cell.SetCellValue(dataModels[i].title3.ToString());
                  if (j == 3)
                      cell.SetCellValue(dataModels[i].title4.ToString());
                  if (j == 4)
                      cell.SetCellValue(dataModels[i].title5.ToString());
                  if (j == 5)
                      cell.SetCellValue(dataModels[i].title6.ToString());
                  if (j == 6)
                      cell.SetCellValue(dataModels[i].title7.ToString());
                  if (j == 7)
                      cell.SetCellValue(dataModels[i].title8.ToString());
                  if (j == 8)
                      cell.SetCellValue(dataModels[i].title9.ToString());
                  if (j == 9)
                      cell.SetCellValue(dataModels[i].title10.ToString());
                  if (j == 10)
                      cell.SetCellValue(dataModels[i].title11.ToString());
                  cell.CellStyle = cellStyle;
              }
          }

          //设置导出文件路径
          string path = textBox2.Text;

          //设置新建文件路径及名称
          string savePath = path + "合并" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".xls";

          //创建文件
          FileStream file = new FileStream(savePath, FileMode.CreateNew, FileAccess.Write);

          //创建一个 IO 流
          MemoryStream ms = new MemoryStream();

          //写入到流
          workbook.Write(ms);

          //转换为字节数组
          byte[] bytes = ms.ToArray();

          file.Write(bytes, 0, bytes.Length);
          file.Flush();

          //还可以调用下面的方法,把流输出到浏览器下载
          //OutputClient(bytes);

          //释放资源
          bytes = null;

          ms.Close();
          ms.Dispose();

          file.Close();
          file.Dispose();

          workbook.Close();
          sheet = null;
          workbook = null;
      }
      catch (Exception ex)
      {

      }
  }

以上就是C#封装一个快速读取写入操作excel的工具类的详细内容,更多关于C#读取写入excel的资料请关注脚本之家其它相关文章!

相关文章

  • C# 如何使用ajax请求

    C# 如何使用ajax请求

    这篇文章主要介绍了C# 如何使用ajax请求,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C#使用NUnit进行单元测试详解

    C#使用NUnit进行单元测试详解

    NUnit是一个开源的.Net单元测试框架,经常被用来在.Net体系下做白盒测试,本文主要为大家详细介绍了如何C#如何使用NUnit进行单元测试,感兴趣的可以了解下
    2023-12-12
  • C#自定义字符串补0函数实例

    C#自定义字符串补0函数实例

    这篇文章主要介绍了C#自定义字符串补0函数,通过一个自定义函数形式实例分析了C#操作字符串实现补零操作的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • 基于C#动手实现网络服务器Web Server

    基于C#动手实现网络服务器Web Server

    这篇文章主要为大家详细介绍了基于C#动手实现网络服务器Web Server,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • C# Linq延迟查询的执行实例代码

    C# Linq延迟查询的执行实例代码

    这篇文章主要介绍了C# Linq延迟查询执行的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 基于使用BeginInvoke,EndInvoke异步调用委托的实现代码

    基于使用BeginInvoke,EndInvoke异步调用委托的实现代码

    本篇文章是对使用BeginInvoke,EndInvoke异步调用委托的实现代码进行了分析介绍,需要的朋友参考下
    2013-05-05
  • c# Newtonsoft.Json 常用方法总结

    c# Newtonsoft.Json 常用方法总结

    这篇文章主要介绍了c# Newtonsoft.Json 常用方法的相关资料,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-02-02
  • C#抓取网络图片保存到本地的实现方法

    C#抓取网络图片保存到本地的实现方法

    下面小编就为大家分享一篇C#抓取网络图片保存到本地的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • 基于C#实现简单的音乐播放器

    基于C#实现简单的音乐播放器

    这篇文章主要介绍了如何基于C#实现简单的音乐播放器,考虑到需求中的界面友好和跨版本兼容性,我们可以选择选择Windows Forms作为开发平台,Windows Forms提供了一个简单而强大的方法来创建桌面应用程序,文中通过代码示例给大家讲解的非常详细,需要的朋友可以参考下
    2024-05-05
  • WMI获取硬件信息封装函数方法(联想台式机出厂编号 CPUID BIOS序列号 硬盘信息 显卡信息 MAC地址)

    WMI获取硬件信息封装函数方法(联想台式机出厂编号 CPUID BIOS序列号 硬盘信息 显卡信息 MAC地址)

    这篇文章主要介绍了WMI获取硬件信息的方法,硬件信息有:联想台式机出厂编号 CPUID BIOS序列号 硬盘信息 显卡信息 MAC地址
    2013-11-11

最新评论