C# 一个快速读取写入操作execl的方法封装

news2024/11/16 17:28:44

在这里插入图片描述
在这里插入图片描述
这里封装了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)
      {

      }
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1420017.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024.1.29 关于 Redis 缓存详解

目录 缓存基本概念 二八定律 Redis 作为缓存 缓存更新策略 定期生成 实时生成 内存淘汰策略 缓存使用的注意事项 关于缓存预热 关于缓存穿透 关于缓存雪崩 关于缓存击穿&#xff08;瘫痪&#xff09; 缓存基本概念 所谓缓存&#xff0c;其实就是将一部分常用数据放…

向日葵企业“云策略”升级 支持Android 被控策略设置

此前&#xff0c;贝锐向日葵推出了适配PC企业客户端的云策略功能&#xff0c;这一功能支持管理平台统一修改设备设置&#xff0c;上万设备实时下发实时生效&#xff0c;很好的解决了当远程控制方案部署后&#xff0c;想要灵活调整配置需要逐台手工操作的痛点&#xff0c;大幅提…

计算机网络-数据交换方式(电路交换 报文交换 分组交换及其两种方式 )

文章目录 为什么要数据交换&#xff1f;总览电路交换电路交换的各个阶段建立连接数据传输释放连接 电路交换的特点电路交换的优缺点 报文交换报文交换流程报文交换的优缺点 分组交换分组交换流程分组交换的优缺点 数据交换方式的选择分组交换的两种方式数据报方式数据报方式的特…

正则表达式(RE)

什么是正则表达式 正则表达式&#xff0c;又称规则表达式&#xff08;Regular Expression&#xff09;。正则表达式通常被用来检索、替换那些符合某个规则的文本 正则表达式的作用 验证数据的有效性替换文本内容从字符串中提取子字符串 匹配单个字符 字符功能.匹配任意1个…

(一)Spring 核心之控制反转(IoC)—— 配置及使用

目录 一. 前言 二. IoC 基础 2.1. IoC 是什么 2.2. IoC 能做什么 2.3. IoC 和 DI 是什么关系 三. IoC 配置的三种方式 3.1. XML 配置 3.2. Java 配置 3.3. 注解配置 四. 依赖注入的三种方式 4.1. 属性注入&#xff08;setter 注入&#xff09; 4.2. 构造方法注入&a…

ES Serverless让日志检索更加便捷

前言 在项目中,或者开发过程中,出现bug或者其他线上问题,开发人员可以通过查看日志记录来定位问题。通过日志定位 bug 是一种常见的软件开发和运维技巧,只有观察日志才能追踪到具体代码。在软件开发过程中,开发人员会在代码中添加日志记录,以记录程序的运行情况和异常信…

【蓝桥杯日记】复盘篇二:分支结构

前言 本篇笔记主要进行复盘的内容是分支结构&#xff0c;通过学习分支结构从而更好巩固之前所学的内容。 目录 前言 目录 &#x1f34a;1.数的性质 分析&#xff1a; 知识点&#xff1a; &#x1f345;2.闰年判断 说明/提示 分析&#xff1a; 知识点&#xff1a; &am…

【Linux操作系统】:Linux开发工具编辑器vim

目录 Linux 软件包管理器 yum 什么是软件包 注意事项 查看软件包 如何安装软件 如何卸载软件 Linux 开发工具 Linux编辑器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 插入模式 插入模式切换为命令模式 移动光标 删除文字 复制 替换 撤销 跳至指…

C++——list的使用及其模拟实现

list 文章目录 list1. 基本使用1.1 list对象的定义1.2 增&#xff08;插入数据&#xff09;1.3 删&#xff08;删除数据&#xff09;1.4 遍历访问 2. 模拟实现2.1 节点类ListNode2.2 封装ListNode类&#xff0c;实现list基本功能2.3 实现迭代器iterator2.3.1 实现const迭代器co…

使用Hutool工具包解析、生成XML文件

说明&#xff1a;当我们在工作中需要将数据转为XML文件、或者读取解析XML文件时&#xff0c;使用Hutool工具包中的XMLUtil相关方法是最容易上手的方法&#xff0c;本文介绍如何使用Hutool工具包来解析、生成XML文件。 开始之前&#xff0c;需要导入Hutool工具包的依赖 <de…

力扣hot100 柱状图中最大的矩形 单调栈

Problem: 84. 柱状图中最大的矩形 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 参考地址 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) Code class Solution {public static int largestRectangleArea(int[] height){Stack&l…

疯狂的方块

欢迎来到程序小院 疯狂的方块 玩法&#xff1a;两个以上相同颜色的方块连在一起&#xff0c;点击即可消除&#xff0c;不要让方块到达顶部&#xff0c;消除底部方块哦^^。开始游戏https://www.ormcc.com/play/gameStart/263 html <div id"gameDiv"> <canv…

fiber学习

React原理&#xff1a;通俗易懂的 Fiber - 掘金

nacos启动失败解决

报错信息 Caused by: com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large (2,937 > 2,048). You can change this value on the server by setting the ‘max_allowed_packet’ variable. 情景复现 最近使用mac正在运行一个nacos的spri…

treeview

QML自定义一个TreeView&#xff0c;使用ListView递归 在 Qt5 的 QtQuick.Controls 2.x 中还没有 TreeView 这个控件&#xff08;在 Qt6 中出了一个继承自 TableView 的 TreeView&#xff09;&#xff0c;而且 QtQuick.Controls 1.x 中的也需要配合 C model 来自定义&#xff0c…

Win10 双网卡实现同时上内外网

因为需要同时上内网和外网&#xff0c;但公司做了网络隔离&#xff0c;不能同时上内外网&#xff0c;所以多加了块无线网卡&#xff0c;配置双网关实现同时上内外网&#xff0c;互不影响 打开 Windows PowerShell&#xff08;管理员&#xff09;&#xff0c;输入&#xff1a;ro…

Github 2024-01-30 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-01-30统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4TypeScript项目2Jupyter Notebook项目2HTML项目1Rust项目1C项目1 稳定扩散Web UI 创建周期&…

C++核心编程:类和对象 笔记

4.类和对象 C面向对象的三大特性为:封装,继承,多态C认为万事万物都皆为对象&#xff0c;对象上有其属性和行为 例如&#xff1a; 人可以作为对象&#xff0c;属性有姓名、年龄、身高、体重...,行为有走、跑、跳、说话...车可以作为对象&#xff0c;属性有轮胎、方向盘、车灯…

万兆网络数据传输-scp加速

在万兆甚至更高的网络带宽场景下 scp 的传输效率并不如人意。毕竟 scp 是旧时代的产物&#xff0c;那时千兆网络都很罕见。以下通过修改压缩方式的方法提升数据的传输速度。同时也采用 nc &#xff0c; bbcp 和 rsync 进行了对比测试。 目录 scp采用默认方式更改压缩算法为 aes…

seata 分布式

一、下载安装seata 已经下载好的朋友可以跳过这个步骤。这里下载的是seata1.6.1这个版本。 1、进入seata官网 地址&#xff1a; https://seata.io/zh-cn/index.html 2、进入下载 3、点击下载地址 下载地址&#xff1a; https://github.com/seata/seata 二、配置seata 进入c…