C#的Excel导入、导出

本篇主要介绍C#的Excel导入、导出,供大家参考,具体内容如下

一. 介绍
1.1 第三方类库:NPOI

说明:NPOI是POI项目的.NET 版本,可用于Excel、Word的读写操作。

优点:不用装Office环境。

下载地址:http://npoi.codeplex.com/releases

1.2 Excel结构介绍

工作簿(Workbook):每个Excel文件可理解为一个工作簿。

工作表(Sheet):一个工作簿(Workbook)可以包含多个工作表。

行(row):一个工作表(Sheet)可以包含多个行。

二. Excel导入
2.1 操作流程

2.2 NPOI操作代码

说明:把Excel文件转换为List<T>

步骤:

①读取Excel文件并以此初始化一个工作簿(Workbook);

②从工作簿上获取一个工作表(Sheet);默认为工作薄的第一个工作表;

③遍历工作表所有的行(row);默认从第二行开始遍历,第一行(序号0)为单元格头部;

④遍历行的每一个单元格(cell),根据一定的规律赋值给对象的属性。

代码:

/// <summary>
/// 从Excel2003取数据并记录到List集合里
/// </summary>
/// <param name="cellHeard">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
/// <param name="filePath">保存文件绝对路径</param>
/// <param name="errorMsg">错误信息</param>
/// <returns>转换好的List对象集合</returns>
private static List<T> Excel2003ToEntityList<T>(Dictionary<string, string> cellHeard, string filePath, out StringBuilder errorMsg) where T : new()
{
  errorMsg = new StringBuilder(); // 错误信息,Excel转换到实体对象时,会有格式的错误信息
  List<T> enlist = new List<T>(); // 转换后的集合
  List<string> keys = cellHeard.Keys.ToList(); // 要赋值的实体对象属性名称
  try
  {
    using (FileStream fs = File.OpenRead(filePath))
    {
      HSSFWorkbook workbook = new HSSFWorkbook(fs);
      HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0); // 获取此文件第一个Sheet页
      for (int i = 1; i <= sheet.LastRowNum; i++) // 从1开始,第0行为单元头
      {
        // 1.判断当前行是否空行,若空行就不在进行读取下一行操作,结束Excel读取操作
        if (sheet.GetRow(i) == null)
        {
          break;
        }

        T en = new T();
        string errStr = ""; // 当前行转换时,是否有错误信息,格式为:第1行数据转换异常:XXX列;
        for (int j = 0; j < keys.Count; j++)
        {
          // 2.若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.TrueName
          if (keys[j].IndexOf(".") >= 0)
          {
            // 2.1解析子类属性
            string[] properotyArray = keys[j].Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
            string subClassName = properotyArray[0]; // '.'前面的为子类的名称
            string subClassProperotyName = properotyArray[1]; // '.'后面的为子类的属性名称
            System.Reflection.PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
            if (subClassInfo != null)
            {
              // 2.1.1 获取子类的实例
              var subClassEn = en.GetType().GetProperty(subClassName).GetValue(en, null);
              // 2.1.2 根据属性名称获取子类里的属性信息
              System.Reflection.PropertyInfo properotyInfo = subClassInfo.PropertyType.GetProperty(subClassProperotyName);
              if (properotyInfo != null)
              {
                try
                {
                  // Excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
                  properotyInfo.SetValue(subClassEn, GetExcelCellToProperty(properotyInfo.PropertyType, sheet.GetRow(i).GetCell(j)), null);
                }
                catch (Exception e)
                {
                  if (errStr.Length == 0)
                  {
                    errStr = "第" + i + "行数据转换异常:";
                  }
                  errStr += cellHeard[keys[j]] + "列;";
                }

              }
            }
          }
          else
          {
            // 3.给指定的属性赋值
            System.Reflection.PropertyInfo properotyInfo = en.GetType().GetProperty(keys[j]);
            if (properotyInfo != null)
            {
              try
              {
                // Excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
                properotyInfo.SetValue(en, GetExcelCellToProperty(properotyInfo.PropertyType, sheet.GetRow(i).GetCell(j)), null);
              }
              catch (Exception e)
              {
                if (errStr.Length == 0)
                {
                  errStr = "第" + i + "行数据转换异常:";
                }
                errStr += cellHeard[keys[j]] + "列;";
              }
            }
          }
        }
        // 若有错误信息,就添加到错误信息里
        if (errStr.Length > 0)
        {
          errorMsg.AppendLine(errStr);
        }
        enlist.Add(en);
      }
    }
    return enlist;
  }
  catch (Exception ex)
  {
    throw ex;
  }
}

2.3 C#逻辑操作代码

说明:对Excel转换后的List<T>进行后续操作;如:检测有效性、持久化存储等等

步骤:

①调用2.2代码,把Excel文件转换为List<T>。

②对List<T>进行有效性检测:必填项是否为空、是否有重复记录等等。

③对List<T>进行持久化存储操作。如:存储到数据库。

④返回操作结果。

代码:

public void ImportExcel(HttpContext context)
{
  StringBuilder errorMsg = new StringBuilder(); // 错误信息
  try
  {

    #region 1.获取Excel文件并转换为一个List集合

    // 1.1存放Excel文件到本地服务器
    HttpPostedFile filePost = context.Request.Files["filed"]; // 获取上传的文件
    string filePath = ExcelHelper.SaveExcelFile(filePost); // 保存文件并获取文件路径

    // 单元格抬头
    // key:实体对象属性名称,可通过反射获取值
    // value:属性对应的中文注解
    Dictionary<string, string> cellheader = new Dictionary<string, string> {
      { "Name", "姓名" },
      { "Age", "年龄" },
      { "GenderName", "性别" },
      { "TranscriptsEn.ChineseScores", "语文成绩" },
      { "TranscriptsEn.MathScores", "数学成绩" },
    };

    // 1.2解析文件,存放到一个List集合里
    List<UserEntity> enlist = ExcelHelper.ExcelToEntityList<UserEntity>(cellheader, filePath, out errorMsg);

    #endregion

    #region 2.对List集合进行有效性校验

    #region 2.1检测必填项是否必填

    for (int i = 0; i < enlist.Count; i++)
    {
      UserEntity en = enlist[i];
      string errorMsgStr = "第" + (i + 1) + "行数据检测异常:";
      bool isHaveNoInputValue = false; // 是否含有未输入项
      if (string.IsNullOrEmpty(en.Name))
      {
        errorMsgStr += "姓名列不能为空;";
        isHaveNoInputValue = true;
      }
      if (isHaveNoInputValue) // 若必填项有值未填
      {
        en.IsExcelVaildateOK = false;
        errorMsg.AppendLine(errorMsgStr);
      }
    }

    #endregion

    #region 2.2检测Excel中是否有重复对象

    for (int i = 0; i < enlist.Count; i++)
    {
      UserEntity enA = enlist[i];
      if (enA.IsExcelVaildateOK == false) // 上面验证不通过,不进行此步验证
      {
        continue;
      }

      for (int j = i + 1; j < enlist.Count; j++)
      {
        UserEntity enB = enlist[j];
        // 判断必填列是否全部重复
        if (enA.Name == enB.Name)
        {
          enA.IsExcelVaildateOK = false;
          enB.IsExcelVaildateOK = false;
          errorMsg.AppendLine("第" + (i + 1) + "行与第" + (j + 1) + "行的必填列重复了");
        }
      }
    }

    #endregion

    // TODO:其他检测

    #endregion

    // 3.TODO:对List集合持久化存储操作。如:存储到数据库

    // 4.返回操作结果
    bool isSuccess = false;
    if (errorMsg.Length == 0)
    {
      isSuccess = true; // 若错误信息成都为空,表示无错误信息
    }
    var rs = new { success = isSuccess, msg = errorMsg.ToString(), data = enlist };
    System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
    context.Response.ContentType = "text/plain";
    context.Response.Write(js.Serialize(rs)); // 返回Json格式的内容
  }
  catch (Exception ex)
  {
     throw ex;
  }
}
  

3. Excel导出
3.1 导出流程

3.2 NPOI操作代码

说明:把List<T>转换为Excel

步骤:

①创建一个工作簿(Workbook);

②在工作簿上创建一个工作表(Sheet);

③在工作表上创建第一行(row),第一行为列头,依次写入cellHeard的值(做为列名)。

④循环遍历List<T>集合,每循环一遍创建一个行(row),然后根据cellHeard的键(属性名称)依次从List<T>中的实体对象取值存放到单元格内。

代码:

/// <summary>
/// 实体类集合导出到Excle2003
/// </summary>
/// <param name="cellHeard">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
/// <param name="enList">数据源</param>
/// <param name="sheetName">工作表名称</param>
/// <returns>文件的下载地址</returns>
public static string EntityListToExcel2003(Dictionary<string, string> cellHeard, IList enList, string sheetName)
{
  try
  {
    string fileName = sheetName + "-" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xls"; // 文件名称
    string urlPath = "UpFiles/ExcelFiles/" + fileName; // 文件下载的URL地址,供给前台下载
    string filePath = HttpContext.Current.Server.MapPath("\\" + urlPath); // 文件路径

    // 1.检测是否存在文件夹,若不存在就建立个文件夹
    string directoryName = Path.GetDirectoryName(filePath);
    if (!Directory.Exists(directoryName))
    {
      Directory.CreateDirectory(directoryName);
    }

    // 2.解析单元格头部,设置单元头的中文名称
    HSSFWorkbook workbook = new HSSFWorkbook(); // 工作簿
    ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
    IRow row = sheet.CreateRow(0);
    List<string> keys = cellHeard.Keys.ToList();
    for (int i = 0; i < keys.Count; i++)
    {
      row.CreateCell(i).SetCellValue(cellHeard[keys[i]]); // 列名为Key的值
    }

    // 3.List对象的值赋值到Excel的单元格里
    int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
    foreach (var en in enList)
    {
      IRow rowTmp = sheet.CreateRow(rowIndex);
      for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
      {
        string cellValue = ""; // 单元格的值
        object properotyValue = null; // 属性的值
        System.Reflection.PropertyInfo properotyInfo = null; // 属性的信息

        // 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
        if (keys[i].IndexOf(".") >= 0)
        {
          // 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
          string[] properotyArray = keys[i].Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
          string subClassName = properotyArray[0]; // '.'前面的为子类的名称
          string subClassProperotyName = properotyArray[1]; // '.'后面的为子类的属性名称
          System.Reflection.PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
          if (subClassInfo != null)
          {
            // 3.1.2 获取子类的实例
            var subClassEn = en.GetType().GetProperty(subClassName).GetValue(en, null);
            // 3.1.3 根据属性名称获取子类里的属性类型
            properotyInfo = subClassInfo.PropertyType.GetProperty(subClassProperotyName);
            if (properotyInfo != null)
            {
              properotyValue = properotyInfo.GetValue(subClassEn, null); // 获取子类属性的值
            }
          }
        }
        else
        {
          // 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
          properotyInfo = en.GetType().GetProperty(keys[i]);
          if (properotyInfo != null)
          {
            properotyValue = properotyInfo.GetValue(en, null);
          }
        }

        // 3.3 属性值经过转换赋值给单元格值
        if (properotyValue != null)
        {
          cellValue = properotyValue.ToString();
          // 3.3.1 对时间初始值赋值为空
          if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
          {
            cellValue = "";
          }
        }

        // 3.4 填充到Excel的单元格里
        rowTmp.CreateCell(i).SetCellValue(cellValue);
      }
      rowIndex++;
    }

    // 4.生成文件
    FileStream file = new FileStream(filePath, FileMode.Create);
    workbook.Write(file);
    file.Close();

    // 5.返回下载路径
    return urlPath;
  }
  catch (Exception ex)
  {
    throw ex;
  }
}

3.3 C#逻辑操作代码

说明:对Excel转换后的List<T>进行后续操作;如:检测有效性、持久化存储等等

步骤:

①获取List<T>集合。

②调用3.2,将List<T>转换为Excel文件。

③服务器存储Excel文件并返回下载链接。

代码:

public void ExportExcel(HttpContext context)
{
  try
  {
    // 1.获取数据集合
    List<UserEntity> enlist = new List<UserEntity>() {
      new UserEntity{Name="刘一",Age=22,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=80,MathScores=90}},
      new UserEntity{Name="陈二",Age=23,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=81,MathScores=91} },
      new UserEntity{Name="张三",Age=24,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=82,MathScores=92} },
      new UserEntity{Name="李四",Age=25,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=83,MathScores=93} },
      new UserEntity{Name="王五",Age=26,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=84,MathScores=94} },
    };

    // 2.设置单元格抬头
    // key:实体对象属性名称,可通过反射获取值
    // value:Excel列的名称
    Dictionary<string, string> cellheader = new Dictionary<string, string> {
      { "Name", "姓名" },
      { "Age", "年龄" },
      { "GenderName", "性别" },
      { "TranscriptsEn.ChineseScores", "语文成绩" },
      { "TranscriptsEn.MathScores", "数学成绩" },
    };

    // 3.进行Excel转换操作,并返回转换的文件下载链接
    string urlPath = ExcelHelper.EntityListToExcel2003(cellheader, enlist, "学生成绩");
    System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
    context.Response.ContentType = "text/plain";
    context.Response.Write(js.Serialize(urlPath)); // 返回Json格式的内容
  }
  catch (Exception ex)
  {
    throw ex;
  }
}

3.4 代码分析

核心代码主要是cellheader与List<T>之间的映射关系:

四. 源码下载
4.1 运行图

源码下载:http://xiazai.jb51.net/201605/yuanma/C#-Excel(jb51.net).rar

以上就是本文的全部内容,希望能够对大家的学习有所帮助。

(0)

相关推荐

  • C#使用RenderControl将GridView控件导出到EXCEL的方法

    本文实例展示了C#使用RenderControl将GridView控件导出到EXCEL的方法,是非常实用的一个功能,分享给大家供大家参考.具体如下: 主要功能代码如下: // 把GridView输出到Excel文件 private void ExportExcel(GridView gridView, string title, string title2, string fileName) { int nHideCols = 0; //如果不想输出出某列,将Visible设为false即可 f

  • C#数据导入/导出Excel文件及winForm导出Execl总结

    一.asp.net中导出Execl的方法: 在asp.net中导出Execl有两种方法,一种是将导出的文件存放在服务器某个文件夹下面,然后将文件地址输出在浏览器上:一种是将文件直接将文件输出流写给浏览器.在Response输出时,\t分隔的数据,导出execl时,等价于分列,\n等价于换行. 1.将整个html全部输出execl 此法将html中所有的内容,如按钮,表格,图片等全部输出到Execl中. 复制代码 代码如下: Response.Clear(); Response.Buffer= t

  • C#导入导出EXCEL文件的代码实例

    复制代码 代码如下: using System;using System.Data;using System.Data.OleDb; namespace ZFSoft.Joint{    public class ExcelIO    {        private int _ReturnStatus;        private string _ReturnMessage; /// <summary>        /// 执行返回状态        /// </summary&g

  • c# 将Datatable数据导出到Excel表格中

    话不多说,请看代码: public FileResult GetExcelFile() { if (Session["beginDate"] != null) { string bdate = Session["beginDate"].ToString(); DateTime ld = Convert.ToDateTime(Session["lastDate"].ToString()); DateTime ldate = ld.AddDays(1

  • 让C# Excel导入导出 支持不同版本Office

    问题:最近在项目中遇到,不同客户机安装不同Office版本,在导出Excel时,发生错误. 找不到Excel Com组件,错误信息如下.  未能加载文件或程序集"Microsoft.Office.Interop.Excel, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"或它的某一个依赖项.系统找不到指定的文件. 解决方法: 1.引用高版本的的Excel.dll组件,最新版本14.0.0 防止客户安

  • C#如何将DataTable导出到Excel解决方案

    最近,由于公司项目中需要将系统内用户操作的所有日志进行转存备份,考虑到以后可能还需要还原,所以最后决定将日志数据备份到Excel中. 下面是我项目当中Excel.cs这个类的全部代码,通过这个类可以很容易地将DataTable中的数据导入到Excel方法中. 首先,必须要下载NPOI.dll这个程序集, 类代码如下: 复制代码 代码如下: using System; using NPOI.HSSF; using NPOI.HPSF; using NPOI.HSSF.UserModel; usin

  • C#导出GridView数据到Excel文件类实例

    本文实例讲述了C#导出GridView数据到Excel文件类.分享给大家供大家参考.具体如下: 这段C#代码自定义了一个封装类,用于将GridView数据导出到Excel文件 using System; using System.Web; using System.Web.UI; using System.IO; using System.Web.UI.WebControls; namespace DotNet.Utilities { public class ExportExcel { pro

  • C#自定义导出数据到Excel的类实例

    本文实例讲述了C#自定义导出数据到Excel的类.分享给大家供大家参考.具体如下: C#自定义Excel操作类,可以用于将DataTable导出到Excel文件,从Excel文件读取数据. using System; using System.IO; using System.Data; using System.Collections; using System.Data.OleDb; using System.Web; using System.Web.UI; using System.We

  • C#导出数据到Excel文件的方法

    本文实例讲述了C#导出数据到Excel文件的方法.分享给大家供大家参考.具体实现方法如下: /// <summary> /// 导出到Excel类,项目需引用Microsodt.Office.Interop.Excel, /// 类文件需using System.Data与System.Windows.Forms命名空间 /// </summary> public class CToExcel { /// <summary> /// 导出到Excel /// </

  • Java实现Excel导入导出数据库的方法示例

    本文实例讲述了Java实现Excel导入导出数据库的方法.分享给大家供大家参考,具体如下: 由于公司需求,想通过Excel导入数据添加到数据库中,而导入的Excel的字段是不固定的,使用得通过动态创建数据表,每个Excel对应一张数据表,怎么动态创建数据表,可以参考前面一篇<java使用JDBC动态创建数据表及SQL预处理的方法>. 下面主要讲讲怎么将Excel导入到数据库中,直接上代码:干货走起~~ ExcellToObjectUtil 类 主要功能是讲Excel中的数据导入到数据库中,有几

  • Java实现Excel导入导出操作详解

    目录 前言 1. 功能测试 1.1 测试准备 1.2 数据导入 1.2.1 导入解析为JSON 1.2.2 导入解析为对象(基础) 1.2.3 导入解析为对象(字段自动映射) 1.2.4 导入解析为对象(获取行号) 1.2.5 导入解析为对象(获取原始数据) 1.2.6 导入解析为对象(获取错误提示) 1.2.7 导入解析为对象(限制字段长度) 1.2.8 导入解析为对象(必填字段验证) 1.2.9 导入解析为对象(数据唯一性验证) 1.3 数据导出 1.3.1 动态导出(基础) 1.3.2 动

  • C#使用NPOI实现Excel导入导出功能

    本文实例为大家分享了C#使用NPOI实现Excel导入导出的具体代码,供大家参考,具体内容如下 Excel导入 使用OpenFileDiolog控件和button结合,选择文件导入,将路径显示在文本框 设置按钮点击事件,将文件路径赋给textBox.Text private void Department_SUM_Click(object sender, EventArgs e)         {             OpenFileDialog open = new OpenFileDi

  • 使用纯前端JavaScript实现Excel导入导出方法过程详解

    公司最近要为某国企做一个**统计和管理系统, 具体要求包含 Excel导入导出根据导入的数据进行展示报表图表展示(包括柱状图,折线图,饼图),而且还要求要有动画效果,扁平化风格Excel导出,并要提供客户端来管理Excel 文件... 要求真多! 现在总算是完成了,于是将我的经验分析出来. 在整个项目架构中,首先就要解决Excel导入的问题. 由于公司没有自己的框架做Excel IO,就只有通过其他渠道了. 嗯,我在github上找到了一个开源库xlsx,通过npm方式来安装. npm inst

  • SpringBoot集成POI实现Excel导入导出的示例详解

    目录 知识准备 什么是POI POI中基础概念 实现案例 Pom依赖 导出Excel 导入Excel 示例源码 知识准备 需要了解POI工具,以及POI对Excel中的对象的封装对应关系. 什么是POI Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能.POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”. A

  • 简单的excel导入导出示例分享

    复制代码 代码如下: /// <summary>        /// 导出Excel        /// </summary>        /// <param name="stime"></param>        /// <param name="etime"></param>        /// <returns></returns>        pub

  • 让C# Excel导入导出 支持不同版本Office

    问题:最近在项目中遇到,不同客户机安装不同Office版本,在导出Excel时,发生错误.找不到Excel Com组件,错误信息如下. 未能加载文件或程序集“Microsoft.Office.Interop.Excel, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”或它的某一个依赖项.系统找不到指定的文件. 解决方法: 1.引用高版本的的Excel.dll组件,最新版本14.0.0 防止客户安装高版本如Of

  • java实现Excel的导入导出

    本文实例为大家分享了java实现Excel导入导出的具体代码,供大家参考,具体内容如下 一.Excel读写技术 区别: 二.jxl读写基础代码 1.从数据库将数据导出到excel表格 public class JxlExcel { public static void main(String[] args) { //创建Excel文件 String[] title= {"姓名","课程名","分数"}; File file=new File(&q

  • Spring Boot项目如何优雅实现Excel导入与导出功能

    目录 背景 EasyExcel 问题 分析与解决 Spring Boot Excel 导入与导出 依赖引入 Excel 导入 基本导入功能 进阶导入功能 Excel 导出 Excel 导入参数校验 开启校验 校验规则定义 Bean Validation 定义校验规则 ExcelValidator 接口定义校验规则 校验结果接收 异常捕获接收校验结果 controller 方法参数接收校验结果 总结 背景 Excel 导入与导出是项目中经常用到的功能,在 Java 中常用 poi 实现 Excel

随机推荐