翼度科技»论坛 编程开发 .net 查看内容

.NET Core 实现Excel的导入导出

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21

目录

前言

我们在日常开发中对Excel的操作可能会比较频繁,好多功能都会涉及到Excel的操作。在.Net Core中大家可能使用Npoi比较多,这款软件功能也十分强大,而且接近原始编程。但是直接使用Npoi大部分时候我们可能都会自己封装一下,毕竟根据二八原则,我们百分之八十的场景可能都是进行简单的导入导出操作,这里就引出我们的主角Npoi。
NPOI简介

NPOI是指构建在POI 3.x版本之上的一个程序,NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作。NPOI是一个开源的C#读写Excel、WORD等微软OLE2组件文档的项目。
一、安装相对应的程序包

在 .Net Core 中使用NPOI首先必须先安装NPOI;如下图所示:

1.1、在 “管理NuGet程序包” 中的浏览搜索:“NPOI”


点击安装以上两个即可,安装完成之后最好重新编译一下项目以防出错
二、新建Excel帮助类

在项目中新建“ExcelHelper”类;此类用于封装导入导出以及其他配置方法。代码如下:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.IO;
  5. using NPOI;
  6. using System.Text;
  7. using NPOI.HSSF.UserModel;
  8. using NPOI.XSSF.UserModel;
  9. using NPOI.SS.Formula.Eval;
  10. using NPOI.SS.UserModel;
  11. using NPOI.SS.Util;
  12. using System.Text.RegularExpressions;
  13. using System.Reflection;
  14. using System.Collections;
  15. using NPOI.HSSF.Util;
  16. namespace WebApplication1 //命名空间依据自己的项目进行修改
  17. {
  18.     /// <summary>
  19.     /// Excel帮助类
  20.     /// 功能:
  21.     ///   1、导出数据到Excel文件中
  22.     ///   2、将Excel文件的数据导入到List<T>对象集合中
  23.     /// </summary>
  24.     public static class ExcelHelper
  25.     {
  26.         /// <summary>
  27.         /// 导出列名
  28.         /// </summary>
  29.         public static SortedList ListColumnsName;
  30.         #region 从DataTable导出到excel文件中,支持xls和xlsx格式
  31.         #region 导出为xls文件内部方法
  32.         /// <summary>
  33.         /// 从DataTable 中导出到excel
  34.         /// </summary>
  35.         /// <param name="strFileName">excel文件名</param>
  36.         /// <param name="dtSource">datatabe源数据</param>
  37.         /// <param name="strHeaderText">表名</param>
  38.         /// <param name="sheetnum">sheet的编号</param>
  39.         /// <returns></returns>
  40.         static MemoryStream ExportDT(string strFileName, DataTable dtSource, string strHeaderText, Dictionary<string, string> dir, int sheetnum)
  41.         {
  42.             //创建工作簿和sheet
  43.             IWorkbook workbook = new HSSFWorkbook();
  44.             using (Stream writefile = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Read))
  45.             {
  46.                 if (writefile.Length > 0 && sheetnum > 0)
  47.                 {
  48.                     workbook = WorkbookFactory.Create(writefile);
  49.                 }
  50.             }
  51.             ISheet sheet = null;
  52.             ICellStyle dateStyle = workbook.CreateCellStyle();
  53.             IDataFormat format = workbook.CreateDataFormat();
  54.             dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");
  55.             int[] arrColWidth = new int[dtSource.Columns.Count];
  56.             foreach (DataColumn item in dtSource.Columns)
  57.             {
  58.                 arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(Convert.ToString(item.ColumnName)).Length;
  59.             }
  60.             for (int i = 0; i < dtSource.Rows.Count; i++)
  61.             {
  62.                 for (int j = 0; j < dtSource.Columns.Count; j++)
  63.                 {
  64.                     int intTemp = Encoding.GetEncoding(936).GetBytes(Convert.ToString(dtSource.Rows[i][j])).Length;
  65.                     if (intTemp > arrColWidth[j])
  66.                     {
  67.                         arrColWidth[j] = intTemp;
  68.                     }
  69.                 }
  70.             }
  71.             int rowIndex = 0;
  72.             foreach (DataRow row in dtSource.Rows)
  73.             {
  74.                 #region 新建表,填充表头,填充列头,样式
  75.                 if (rowIndex == 0)
  76.                 {
  77.                     string sheetName = strHeaderText + (sheetnum == 0 ? "" : sheetnum.ToString());
  78.                     if (workbook.GetSheetIndex(sheetName) >= 0)
  79.                     {
  80.                         workbook.RemoveSheetAt(workbook.GetSheetIndex(sheetName));
  81.                     }
  82.                     sheet = workbook.CreateSheet(sheetName);
  83.                     #region 表头及样式
  84.                     {
  85.                         sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1));
  86.                         IRow headerRow = sheet.CreateRow(0);
  87.                         headerRow.HeightInPoints = 25;
  88.                         headerRow.CreateCell(0).SetCellValue(strHeaderText);
  89.                         ICellStyle headStyle = workbook.CreateCellStyle();
  90.                         headStyle.Alignment = HorizontalAlignment.Center;
  91.                         IFont font = workbook.CreateFont();
  92.                         font.FontHeightInPoints = 20;
  93.                         font.Boldweight = 700;
  94.                         headStyle.SetFont(font);
  95.                         headerRow.GetCell(0).CellStyle = headStyle;
  96.                         rowIndex = 1;
  97.                     }
  98.                     #endregion
  99.                     #region 列头及样式
  100.                     if (rowIndex == 1)
  101.                     {
  102.                         IRow headerRow = sheet.CreateRow(1);//第二行设置列名
  103.                         ICellStyle headStyle = workbook.CreateCellStyle();
  104.                         headStyle.Alignment = HorizontalAlignment.Center;
  105.                         IFont font = workbook.CreateFont();
  106.                         font.FontHeightInPoints = 10;
  107.                         font.Boldweight = 700;
  108.                         headStyle.SetFont(font);
  109.                         //写入列标题
  110.                         foreach (DataColumn column in dtSource.Columns)
  111.                         {
  112.                             headerRow.CreateCell(column.Ordinal).SetCellValue(dir[column.ColumnName]);
  113.                             headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
  114.                             //设置列宽
  115.                             sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256 * 2);
  116.                         }
  117.                         rowIndex = 2;
  118.                     }
  119.                     #endregion
  120.                 }
  121.                 #endregion
  122.                 #region 填充内容
  123.                 IRow dataRow = sheet.CreateRow(rowIndex);
  124.                 foreach (DataColumn column in dtSource.Columns)
  125.                 {
  126.                     NPOI.SS.UserModel.ICell newCell = dataRow.CreateCell(column.Ordinal);
  127.                     string drValue = row[column].ToString();
  128.                     switch (column.DataType.ToString())
  129.                     {
  130.                         case "System.String": //字符串类型
  131.                             double result;
  132.                             if (isNumeric(drValue, out result))
  133.                             {
  134.                                 //数字字符串
  135.                                 double.TryParse(drValue, out result);
  136.                                 newCell.SetCellValue(result);
  137.                                 break;
  138.                             }
  139.                             else
  140.                             {
  141.                                 newCell.SetCellValue(drValue);
  142.                                 break;
  143.                             }
  144.                         case "System.DateTime": //日期类型
  145.                             DateTime dateV;
  146.                             DateTime.TryParse(drValue, out dateV);
  147.                             newCell.SetCellValue(dateV);
  148.                             newCell.CellStyle = dateStyle; //格式化显示
  149.                             break;
  150.                         case "System.Boolean": //布尔型
  151.                             bool boolV = false;
  152.                             bool.TryParse(drValue, out boolV);
  153.                             newCell.SetCellValue(boolV);
  154.                             break;
  155.                         case "System.Int16": //整型
  156.                         case "System.Int32":
  157.                         case "System.Int64":
  158.                         case "System.Byte":
  159.                             int intV = 0;
  160.                             int.TryParse(drValue, out intV);
  161.                             newCell.SetCellValue(intV);
  162.                             break;
  163.                         case "System.Decimal": //浮点型
  164.                         case "System.Double":
  165.                             double doubV = 0;
  166.                             double.TryParse(drValue, out doubV);
  167.                             newCell.SetCellValue(doubV);
  168.                             break;
  169.                         case "System.DBNull": //空值处理
  170.                             newCell.SetCellValue("");
  171.                             break;
  172.                         default:
  173.                             newCell.SetCellValue(drValue.ToString());
  174.                             break;
  175.                     }
  176.                 }
  177.                 #endregion
  178.                 rowIndex++;
  179.             }
  180.             using (MemoryStream ms = new MemoryStream())
  181.             {
  182.                 workbook.Write(ms, true);
  183.                 ms.Flush();
  184.                 ms.Position = 0;
  185.                 return ms;
  186.             }
  187.         }
  188.         #endregion
  189.         #region 导出为xlsx文件内部方法
  190.         /// <summary>
  191.         /// 从DataTable 中导出到excel
  192.         /// </summary>
  193.         /// <param name="dtSource">DataTable数据源</param>
  194.         /// <param name="strHeaderText">表名</param>
  195.         /// <param name="fs">文件流</param>
  196.         /// <param name="readfs">内存流</param>
  197.         /// <param name="sheetnum">sheet索引</param>
  198.         static void ExportDTI(DataTable dtSource, string strHeaderText, FileStream fs, MemoryStream readfs, Dictionary<string, string> dir, int sheetnum)
  199.         {
  200.             IWorkbook workbook = new XSSFWorkbook();
  201.             if (readfs.Length > 0 && sheetnum > 0)
  202.             {
  203.                 workbook = WorkbookFactory.Create(readfs);
  204.             }
  205.             ISheet sheet = null;
  206.             ICellStyle dateStyle = workbook.CreateCellStyle();
  207.             IDataFormat format = workbook.CreateDataFormat();
  208.             dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");
  209.             //取得列宽
  210.             int[] arrColWidth = new int[dtSource.Columns.Count];
  211.             foreach (DataColumn item in dtSource.Columns)
  212.             {
  213.                 arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(Convert.ToString(item.ColumnName)).Length;
  214.             }
  215.             for (int i = 0; i < dtSource.Rows.Count; i++)
  216.             {
  217.                 for (int j = 0; j < dtSource.Columns.Count; j++)
  218.                 {
  219.                     int intTemp = Encoding.GetEncoding(936).GetBytes(Convert.ToString(dtSource.Rows[i][j])).Length;
  220.                     if (intTemp > arrColWidth[j])
  221.                     {
  222.                         arrColWidth[j] = intTemp;
  223.                     }
  224.                 }
  225.             }
  226.             int rowIndex = 0;
  227.             foreach (DataRow row in dtSource.Rows)
  228.             {
  229.                 #region 新建表,填充表头,填充列头,样式
  230.                 if (rowIndex == 0)
  231.                 {
  232.                     #region 表头及样式
  233.                     {
  234.                         string sheetName = strHeaderText + (sheetnum == 0 ? "" : sheetnum.ToString());
  235.                         if (workbook.GetSheetIndex(sheetName) >= 0)
  236.                         {
  237.                             workbook.RemoveSheetAt(workbook.GetSheetIndex(sheetName));
  238.                         }
  239.                         sheet = workbook.CreateSheet(sheetName);
  240.                         sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1));
  241.                         IRow headerRow = sheet.CreateRow(0);
  242.                         headerRow.HeightInPoints = 25;
  243.                         headerRow.CreateCell(0).SetCellValue(strHeaderText);
  244.                         ICellStyle headStyle = workbook.CreateCellStyle();
  245.                         headStyle.Alignment = HorizontalAlignment.Center;
  246.                         IFont font = workbook.CreateFont();
  247.                         font.FontHeightInPoints = 20;
  248.                         font.Boldweight = 700;
  249.                         headStyle.SetFont(font);
  250.                         headerRow.GetCell(0).CellStyle = headStyle;
  251.                     }
  252.                     #endregion
  253.                     #region 列头及样式
  254.                     {
  255.                         IRow headerRow = sheet.CreateRow(1);
  256.                         ICellStyle headStyle = workbook.CreateCellStyle();
  257.                         headStyle.Alignment = HorizontalAlignment.Center;
  258.                         IFont font = workbook.CreateFont();
  259.                         font.FontHeightInPoints = 10;
  260.                         font.Boldweight = 700;
  261.                         headStyle.SetFont(font);
  262.                         foreach (DataColumn column in dtSource.Columns)
  263.                         {
  264.                             headerRow.CreateCell(column.Ordinal).SetCellValue(dir[column.ColumnName]);
  265.                             headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
  266.                             //设置列宽
  267.                             sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256 * 2);
  268.                         }
  269.                     }
  270.                     #endregion
  271.                     rowIndex = 2;
  272.                 }
  273.                 #endregion
  274.                 #region 填充内容
  275.                 IRow dataRow = sheet.CreateRow(rowIndex);
  276.                 foreach (DataColumn column in dtSource.Columns)
  277.                 {
  278.                     NPOI.SS.UserModel.ICell newCell = dataRow.CreateCell(column.Ordinal);
  279.                     string drValue = row[column].ToString();
  280.                     switch (column.DataType.ToString())
  281.                     {
  282.                         case "System.String": //字符串类型
  283.                             double result;
  284.                             if (isNumeric(drValue, out result))
  285.                             {
  286.                                 double.TryParse(drValue, out result);
  287.                                 newCell.SetCellValue(result);
  288.                                 break;
  289.                             }
  290.                             else
  291.                             {
  292.                                 newCell.SetCellValue(drValue);
  293.                                 break;
  294.                             }
  295.                         case "System.DateTime": //日期类型
  296.                             DateTime dateV;
  297.                             DateTime.TryParse(drValue, out dateV);
  298.                             newCell.SetCellValue(dateV);
  299.                             newCell.CellStyle = dateStyle; //格式化显示
  300.                             break;
  301.                         case "System.Boolean": //布尔型
  302.                             bool boolV = false;
  303.                             bool.TryParse(drValue, out boolV);
  304.                             newCell.SetCellValue(boolV);
  305.                             break;
  306.                         case "System.Int16": //整型
  307.                         case "System.Int32":
  308.                         case "System.Int64":
  309.                         case "System.Byte":
  310.                             int intV = 0;
  311.                             int.TryParse(drValue, out intV);
  312.                             newCell.SetCellValue(intV);
  313.                             break;
  314.                         case "System.Decimal": //浮点型
  315.                         case "System.Double":
  316.                             double doubV = 0;
  317.                             double.TryParse(drValue, out doubV);
  318.                             newCell.SetCellValue(doubV);
  319.                             break;
  320.                         case "System.DBNull": //空值处理
  321.                             newCell.SetCellValue("");
  322.                             break;
  323.                         default:
  324.                             newCell.SetCellValue(drValue.ToString());
  325.                             break;
  326.                     }
  327.                 }
  328.                 #endregion
  329.                 rowIndex++;
  330.             }
  331.             workbook.Write(fs,true);
  332.             fs.Close();
  333.         }
  334.         #endregion
  335.         #region 导出excel表格
  336.         /// <summary>
  337.         ///  DataTable导出到Excel文件,xls文件
  338.         /// </summary>
  339.         /// <param name="dtSource">数据源</param>
  340.         /// <param name="strHeaderText">表名</param>
  341.         /// <param name="strFileName">excel文件名</param>
  342.         /// <param name="dir">DataTable和excel列名对应字典</param>
  343.         /// <param name="sheetRow">每个sheet存放的行数</param>
  344.         public static void ExportDTtoExcel(DataTable dtSource, string strHeaderText, string strFileName, Dictionary<string, string> dir, bool isNew, int sheetRow = 50000)
  345.         {
  346.             int currentSheetCount = GetSheetNumber(strFileName);//现有的页数sheetnum
  347.             if (sheetRow <= 0)
  348.             {
  349.                 sheetRow = dtSource.Rows.Count;
  350.             }
  351.             string[] temp = strFileName.Split('.');
  352.             string fileExtens = temp[temp.Length - 1];
  353.             int sheetCount = (int)Math.Ceiling((double)dtSource.Rows.Count / sheetRow);//sheet数目
  354.             if (temp[temp.Length - 1] == "xls" && dtSource.Columns.Count < 256 && sheetRow < 65536)
  355.             {
  356.                 if (isNew)
  357.                 {
  358.                     currentSheetCount = 0;
  359.                 }
  360.                 for (int i = currentSheetCount; i < currentSheetCount + sheetCount; i++)
  361.                 {
  362.                     DataTable pageDataTable = dtSource.Clone();
  363.                     int hasRowCount = dtSource.Rows.Count - sheetRow * (i - currentSheetCount) < sheetRow ? dtSource.Rows.Count - sheetRow * (i - currentSheetCount) : sheetRow;
  364.                     for (int j = 0; j < hasRowCount; j++)
  365.                     {
  366.                         pageDataTable.ImportRow(dtSource.Rows[(i - currentSheetCount) * sheetRow + j]);
  367.                     }
  368.                     using (MemoryStream ms = ExportDT(strFileName, pageDataTable, strHeaderText, dir, i))
  369.                     {
  370.                         using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
  371.                         {
  372.                             byte[] data = ms.ToArray();
  373.                             fs.Write(data, 0, data.Length);
  374.                             fs.Flush();
  375.                         }
  376.                     }
  377.                 }
  378.             }
  379.             else
  380.             {
  381.                 if (temp[temp.Length - 1] == "xls")
  382.                     strFileName = strFileName + "x";
  383.                 if (isNew)
  384.                 {
  385.                     currentSheetCount = 0;
  386.                 }
  387.                 for (int i = currentSheetCount; i < currentSheetCount + sheetCount; i++)
  388.                 {
  389.                     DataTable pageDataTable = dtSource.Clone();
  390.                     int hasRowCount = dtSource.Rows.Count - sheetRow * (i - currentSheetCount) < sheetRow ? dtSource.Rows.Count - sheetRow * (i - currentSheetCount) : sheetRow;
  391.                     for (int j = 0; j < hasRowCount; j++)
  392.                     {
  393.                         pageDataTable.ImportRow(dtSource.Rows[(i - currentSheetCount) * sheetRow + j]);
  394.                     }
  395.                     FileStream readfs = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Read);
  396.                     MemoryStream readfsm = new MemoryStream();
  397.                     readfs.CopyTo(readfsm);
  398.                     readfs.Close();
  399.                     using (FileStream writefs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
  400.                     {
  401.                         ExportDTI(pageDataTable, strHeaderText, writefs, readfsm, dir, i);
  402.                     }
  403.                     readfsm.Close();
  404.                 }
  405.             }
  406.         }
  407.         /// <summary>
  408.         /// 导出Excel(//超出10000条数据 创建新的工作簿)
  409.         /// </summary>
  410.         /// <param name="dtSource">数据源</param>
  411.         /// <param name="dir">导出Excel表格的字段名和列名的字符串字典实例;例如:dir.Add("IllegalKeywords", "姓名");</param>
  412.         public static XSSFWorkbook ExportExcel(DataTable dtSource, Dictionary<string, string> dir)
  413.         {
  414.             XSSFWorkbook excelWorkbook = new XSSFWorkbook();
  415.             //int columnsCount = columnsNames.GetLength(0);
  416.             int columnsCount = dir.Count;
  417.             if (columnsCount > 0)
  418.             {
  419.                 ListColumnsName = new SortedList(new NoSort());
  420.                 //for (int i = 0; i < columnsCount; i++)
  421.                 //{
  422.                 //    ListColumnsName.Add(columnsNames[i, 0], columnsNames[i, 1]);
  423.                 //}
  424.                 foreach (KeyValuePair<string,string> item in dir)
  425.                 {
  426.                     ListColumnsName.Add(item.Key, item.Value);
  427.                 }
  428.                 if (ListColumnsName == null || ListColumnsName.Count == 0)
  429.                 {
  430.                     throw (new Exception("请对ListColumnsName设置要导出的列明!"));
  431.                 }
  432.                 else
  433.                 {
  434.                     excelWorkbook = InsertRow(dtSource);
  435.                 }
  436.             }
  437.             else
  438.             {
  439.                 throw (new Exception("请对ListColumnsName设置要导出的列明!"));
  440.             }
  441.             return excelWorkbook;
  442.         }
  443.         #endregion
  444.         /// <summary>
  445.         /// 创建Excel文件
  446.         /// </summary>
  447.         /// <param name="filePath"></param>
  448.         private static XSSFWorkbook CreateExcelFile()
  449.         {
  450.             XSSFWorkbook xssfworkbook = new XSSFWorkbook();
  451.             //右击文件“属性”信息
  452.             #region 文件属性信息
  453.             {
  454.                 POIXMLProperties props = xssfworkbook.GetProperties();
  455.                 props.CoreProperties.Creator = "Joy";//Excel文件的创建作者
  456.                 props.CoreProperties.Title = "";//Excel文件标题
  457.                 props.CoreProperties.Description = "";//Excel文件备注
  458.                 props.CoreProperties.Category = "";//Excel文件类别信息
  459.                 props.CoreProperties.Subject = "";//Excel文件主题信息
  460.                 props.CoreProperties.Created = DateTime.Now;//Excel文件创建时间
  461.                 props.CoreProperties.Modified = DateTime.Now;//Excel文件修改时间
  462.                 props.CoreProperties.SetCreated(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
  463.                 props.CoreProperties.LastModifiedByUser = "Joy";//Excel文件最后一次保存者
  464.                 props.CoreProperties.SetModified(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));//Excel文件最后一次保存日期
  465.             }
  466.             #endregion
  467.             return xssfworkbook;
  468.         }
  469.         /// <summary>
  470.         /// 创建excel表头
  471.         /// </summary>
  472.         /// <param name="dgv"></param>
  473.         /// <param name="excelSheet"></param>
  474.         private static void CreateHeader(XSSFSheet excelSheet, XSSFWorkbook excelWorkbook, XSSFCellStyle cellStyle)
  475.         {
  476.             int cellIndex = 0;
  477.             //循环导出列
  478.             foreach (System.Collections.DictionaryEntry de in ListColumnsName)
  479.             {
  480.                 XSSFRow newRow = (XSSFRow)excelSheet.CreateRow(0);
  481.                 XSSFCellStyle? headTopStyle = CreateStyle(excelWorkbook, cellStyle,HorizontalAlignment.Center, VerticalAlignment.Center, 18, true, true, "宋体", true, false, false, true, FillPattern.SolidForeground, HSSFColor.Grey25Percent.Index, HSSFColor.Black.Index,FontUnderlineType.None, FontSuperScript.None, false);
  482.                 XSSFCell newCell = (XSSFCell)newRow.CreateCell(cellIndex);
  483.                 newCell.SetCellValue(de.Value.ToString());
  484.                 newCell.CellStyle = headTopStyle;
  485.                 cellIndex++;
  486.             }
  487.         }
  488.         /// <summary>
  489.         /// 插入数据行
  490.         /// </summary>
  491.         private static XSSFWorkbook InsertRow(DataTable dtSource)
  492.         {
  493.             XSSFWorkbook excelWorkbook = CreateExcelFile();
  494.             int rowCount = 0;
  495.             int sheetCount = 1;
  496.             XSSFSheet newsheet = null;
  497.             //循环数据源导出数据集
  498.             newsheet = (XSSFSheet)excelWorkbook.CreateSheet("Sheet" + sheetCount);
  499.             XSSFCellStyle headCellStyle = (XSSFCellStyle)excelWorkbook.CreateCellStyle(); //创建列头单元格实例样式
  500.             CreateHeader(newsheet, excelWorkbook, headCellStyle);
  501.             //单元格内容信息
  502.             foreach (DataRow dr in dtSource.Rows)
  503.             {
  504.                 rowCount++;
  505.                 //超出10000条数据 创建新的工作簿
  506.                 if (rowCount == 10000)
  507.                 {
  508.                     rowCount = 1;
  509.                     sheetCount++;
  510.                     newsheet = (XSSFSheet)excelWorkbook.CreateSheet("Sheet" + sheetCount);
  511.                     CreateHeader(newsheet, excelWorkbook, headCellStyle);
  512.                 }
  513.                 XSSFRow newRow = (XSSFRow)newsheet.CreateRow(rowCount);
  514.                 XSSFCellStyle cellStyle = (XSSFCellStyle)excelWorkbook.CreateCellStyle(); //创建单元格实例样式
  515.                 XSSFCellStyle? style = CreateStyle(excelWorkbook, cellStyle, HorizontalAlignment.Center, VerticalAlignment.Center, 14, true, false);
  516.                 InsertCell(dtSource, dr, newRow, style, excelWorkbook);
  517.             }
  518.             //自动列宽
  519.             //for (int i = 0; i <= dtSource.Columns.Count; i++)
  520.             //{
  521.             //    newsheet.AutoSizeColumn(i, true);
  522.             //}
  523.             return excelWorkbook;
  524.         }
  525.         /// <summary>
  526.         /// 导出数据行
  527.         /// </summary>
  528.         /// <param name="dtSource"></param>
  529.         /// <param name="drSource"></param>
  530.         /// <param name="currentExcelRow"></param>
  531.         /// <param name="excelSheet"></param>
  532.         /// <param name="excelWorkBook"></param>
  533.         private static void InsertCell(DataTable dtSource, DataRow drSource, XSSFRow currentExcelRow, XSSFCellStyle cellStyle, XSSFWorkbook excelWorkBook)
  534.         {
  535.             for (int cellIndex = 0; cellIndex < ListColumnsName.Count; cellIndex++)
  536.             {
  537.                 //列名称
  538.                 string columnsName = ListColumnsName.GetKey(cellIndex).ToString();
  539.                 XSSFCell newCell = null;
  540.                 System.Type rowType = drSource[columnsName].GetType();
  541.                 string drValue = drSource[columnsName].ToString().Trim();
  542.                 switch (rowType.ToString())
  543.                 {
  544.                     case "System.String"://字符串类型
  545.                         drValue = drValue.Replace("&", "&");
  546.                         drValue = drValue.Replace(">", ">");
  547.                         drValue = drValue.Replace("<", "<");
  548.                         newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  549.                         newCell.SetCellValue(drValue);
  550.                         newCell.CellStyle = cellStyle;
  551.                         break;
  552.                     case "System.DateTime"://日期类型
  553.                         DateTime dateV;
  554.                         DateTime.TryParse(drValue, out dateV);
  555.                         newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  556.                         newCell.SetCellValue(dateV);
  557.                         newCell.CellStyle = cellStyle;
  558.                         break;
  559.                     case "System.Boolean"://布尔型
  560.                         bool boolV = false;
  561.                         bool.TryParse(drValue, out boolV);
  562.                         newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  563.                         newCell.SetCellValue(boolV);
  564.                         newCell.CellStyle = cellStyle;
  565.                         break;
  566.                     case "System.Int16"://整型
  567.                     case "System.Int32":
  568.                     case "System.Int64":
  569.                     case "System.Byte":
  570.                         int intV = 0;
  571.                         int.TryParse(drValue, out intV);
  572.                         newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  573.                         newCell.SetCellValue(intV.ToString());
  574.                         newCell.CellStyle = cellStyle;
  575.                         break;
  576.                     case "System.Decimal"://浮点型
  577.                     case "System.Double":
  578.                         double doubV = 0;
  579.                         double.TryParse(drValue, out doubV);
  580.                         newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  581.                         newCell.SetCellValue(doubV);
  582.                         newCell.CellStyle = cellStyle;
  583.                         break;
  584.                     case "System.DBNull"://空值处理
  585.                         newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  586.                         newCell.SetCellValue("");
  587.                         newCell.CellStyle = cellStyle;
  588.                         break;
  589.                     default:
  590.                         throw (new Exception(rowType.ToString() + ":类型数据无法处理!"));
  591.                 }
  592.             }
  593.         }
  594.         /// <summary>
  595.         /// 行内单元格常用样式设置
  596.         /// </summary>
  597.         /// <param name="workbook">Excel文件对象</param>
  598.         /// <param name="cellStyle">Excel文件中XSSFCellStyle对象</param>
  599.         /// <param name="hAlignment">水平布局方式</param>
  600.         /// <param name="vAlignment">垂直布局方式</param>
  601.         /// <param name="fontHeightInPoints">字体大小</param>
  602.         /// <param name="isAddBorder">是否需要边框</param>
  603.         /// <param name="boldWeight">字体加粗 (None = 0,Normal = 400,Bold = 700</param>
  604.         /// <param name="fontName">字体(仿宋,楷体,宋体,微软雅黑...与Excel主题字体相对应)</param>
  605.         /// <param name="isAddBorderColor">是否增加边框颜色</param>
  606.         /// <param name="isItalic">是否将文字变为斜体</param>
  607.         /// <param name="isLineFeed">是否自动换行</param>
  608.         /// <param name="isAddCellBackground">是否增加单元格背景颜色</param>
  609.         /// <param name="fillPattern">填充图案样式(FineDots 细点,SolidForeground立体前景,isAddFillPattern=true时存在)</param>
  610.         /// <param name="cellBackgroundColor">单元格背景颜色(当isAddCellBackground=true时存在)</param>
  611.         /// <param name="fontColor">字体颜色</param>
  612.         /// <param name="underlineStyle">下划线样式(无下划线[None],单下划线[Single],双下划线[Double],会计用单下划线[SingleAccounting],会计用双下划线[DoubleAccounting])</param>
  613.         /// <param name="typeOffset">字体上标下标(普通默认值[None],上标[Sub],下标[Super]),即字体在单元格内的上下偏移量</param>
  614.         /// <param name="isStrikeout">是否显示删除线</param>
  615.         /// <param name="dataFormat">格式化日期显示</param>
  616.         /// <returns></returns>
  617.         public static XSSFCellStyle CreateStyle(XSSFWorkbook workbook, XSSFCellStyle cellStyle, HorizontalAlignment hAlignment, VerticalAlignment vAlignment, short fontHeightInPoints, bool isAddBorder, bool boldWeight, string fontName = "宋体", bool isAddBorderColor = true, bool isItalic = false, bool isLineFeed = true, bool isAddCellBackground = false, FillPattern fillPattern = FillPattern.NoFill, short cellBackgroundColor = HSSFColor.Yellow.Index, short fontColor = HSSFColor.Black.Index, FontUnderlineType underlineStyle =
  618.             FontUnderlineType.None, FontSuperScript typeOffset = FontSuperScript.None, bool isStrikeout = false,string dataFormat="yyyy-MM-dd HH:mm:ss")
  619.         {
  620.             cellStyle.Alignment = hAlignment; //水平居中
  621.             cellStyle.VerticalAlignment = vAlignment; //垂直居中
  622.             cellStyle.WrapText = isLineFeed;//自动换行
  623.             //格式化显示
  624.             XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat();
  625.             cellStyle.DataFormat = format.GetFormat(dataFormat);
  626.             //背景颜色,边框颜色,字体颜色都是使用 HSSFColor属性中的对应调色板索引,关于 HSSFColor 颜色索引对照表,详情参考:https://www.cnblogs.com/Brainpan/p/5804167.html
  627.             //TODO:引用了NPOI后可通过ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillPattern 为单元格背景色的填充样式
  628.             //TODO:十分注意,要设置单元格背景色必须是FillForegroundColor和FillPattern两个属性同时设置,否则是不会显示背景颜色
  629.             if (isAddCellBackground)
  630.             {
  631.                 cellStyle.FillForegroundColor = cellBackgroundColor;//单元格背景颜色
  632.                 cellStyle.FillPattern = fillPattern;//填充图案样式(FineDots 细点,SolidForeground立体前景)
  633.             }
  634.             else
  635.             {
  636.                 cellStyle.FillForegroundColor = HSSFColor.White.Index;//单元格背景颜色
  637.             }
  638.             //是否增加边框
  639.             if (isAddBorder)
  640.             {
  641.                 //常用的边框样式 None(没有),Thin(细边框,瘦的),Medium(中等),Dashed(虚线),Dotted(星罗棋布的),Thick(厚的),Double(双倍),Hair(头发)[上右下左顺序设置]
  642.                 cellStyle.BorderBottom = BorderStyle.Thin;
  643.                 cellStyle.BorderRight = BorderStyle.Thin;
  644.                 cellStyle.BorderTop = BorderStyle.Thin;
  645.                 cellStyle.BorderLeft = BorderStyle.Thin;
  646.             }
  647.             //是否设置边框颜色
  648.             if (isAddBorderColor)
  649.             {
  650.                 //边框颜色[上右下左顺序设置]
  651.                 cellStyle.TopBorderColor = XSSFFont.DEFAULT_FONT_COLOR;//DarkGreen(黑绿色)
  652.                 cellStyle.RightBorderColor = XSSFFont.DEFAULT_FONT_COLOR;
  653.                 cellStyle.BottomBorderColor = XSSFFont.DEFAULT_FONT_COLOR;
  654.                 cellStyle.LeftBorderColor = XSSFFont.DEFAULT_FONT_COLOR;
  655.             }
  656.             /**
  657.              * 设置相关字体样式
  658.              */
  659.             var cellStyleFont = (XSSFFont)workbook.CreateFont(); //创建字体
  660.             //假如字体大小只需要是粗体的话直接使用下面该属性即可
  661.             //cellStyleFont.IsBold = true;
  662.             cellStyleFont.IsBold = boldWeight; //字体加粗
  663.             cellStyleFont.FontHeightInPoints = fontHeightInPoints; //字体大小
  664.             cellStyleFont.FontName = fontName;//字体(仿宋,楷体,宋体 )
  665.             cellStyleFont.Color = fontColor;//设置字体颜色
  666.             cellStyleFont.IsItalic = isItalic;//是否将文字变为斜体
  667.             cellStyleFont.Underline = underlineStyle;//字体下划线
  668.             cellStyleFont.TypeOffset = typeOffset;//字体上标下标
  669.             cellStyleFont.IsStrikeout = isStrikeout;//是否有删除线
  670.             cellStyle.SetFont(cellStyleFont); //将字体绑定到样式
  671.             return cellStyle;
  672.         }
  673.         #endregion
  674.         #region 从excel文件中将数据导出到List<T>对象集合
  675.         /// <summary>
  676.         /// 将制定sheet中的数据导出到DataTable中
  677.         /// </summary>
  678.         /// <param name="sheet">需要导出的sheet</param>
  679.         /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param>
  680.         /// <param name="dir">excel列名和DataTable列名的对应字典</param>
  681.         /// <returns></returns>
  682.         static DataTable ImportDt(ISheet sheet, int HeaderRowIndex, Dictionary<string, string> dir)
  683.         {
  684.             DataTable table = new DataTable();
  685.             IRow headerRow;
  686.             int cellCount;
  687.             try
  688.             {
  689.                 //没有标头或者不需要表头用excel列的序号(1,2,3..)作为DataTable的列名
  690.                 if (HeaderRowIndex < 0)
  691.                 {
  692.                     headerRow = sheet.GetRow(0);
  693.                     cellCount = headerRow.LastCellNum;
  694.                     for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
  695.                     {
  696.                         DataColumn column = new DataColumn(Convert.ToString(i));
  697.                         table.Columns.Add(column);
  698.                     }
  699.                 }
  700.                 //有表头,使用表头做为DataTable的列名
  701.                 else
  702.                 {
  703.                     headerRow = sheet.GetRow(HeaderRowIndex);
  704.                     cellCount = headerRow.LastCellNum;
  705.                     for (int i = headerRow.FirstCellNum; i <cellCount; i++)
  706.                     {
  707.                         //如果excel某一列列名不存在:以该列的序号作为DataTable的列名,如果DataTable中包含了这个序列为名的列,那么列名为重复列名+序号
  708.                         if (headerRow.GetCell(i) == null)
  709.                         {
  710.                             if (table.Columns.IndexOf(Convert.ToString(i)) > 0)
  711.                             {
  712.                                 DataColumn column = new DataColumn(Convert.ToString("重复列名" + i));
  713.                                 table.Columns.Add(column);
  714.                             }
  715.                             else
  716.                             {
  717.                                 DataColumn column = new DataColumn(Convert.ToString(i));
  718.                                 table.Columns.Add(column);
  719.                             }
  720.                         }
  721.                         //excel中的某一列列名不为空,但是重复了:对应的DataTable列名为“重复列名+序号”
  722.                         else if (table.Columns.IndexOf(headerRow.GetCell(i).ToString()) > 0)
  723.                         {
  724.                             DataColumn column = new DataColumn(Convert.ToString("重复列名" + i));
  725.                             table.Columns.Add(column);
  726.                         }
  727.                         else
  728.                         //正常情况,列名存在且不重复:用excel中的列名作为DataTable中对应的列名
  729.                         {
  730.                             string aaa = headerRow.GetCell(i).ToString();
  731.                             string colName = dir.Where(s => s.Value == headerRow.GetCell(i).ToString()).First().Key;
  732.                             DataColumn column = new DataColumn(colName);
  733.                             table.Columns.Add(column);
  734.                         }
  735.                     }
  736.                 }
  737.                 int rowCount = sheet.LastRowNum;
  738.                 for (int i = (HeaderRowIndex + 1); i <= sheet.LastRowNum; i++)//excel行遍历
  739.                 {
  740.                     try
  741.                     {
  742.                         IRow row;
  743.                         if (sheet.GetRow(i) == null)//如果excel有空行,则添加缺失的行
  744.                         {
  745.                             row = sheet.CreateRow(i);
  746.                         }
  747.                         else
  748.                         {
  749.                             row = sheet.GetRow(i);
  750.                         }
  751.                         DataRow dataRow = table.NewRow();
  752.                         for (int j = row.FirstCellNum; j <= cellCount; j++)//excel列遍历
  753.                         {
  754.                             try
  755.                             {
  756.                                 if (row.GetCell(j) != null)
  757.                                 {
  758.                                     switch (row.GetCell(j).CellType)
  759.                                     {
  760.                                         case CellType.String://字符串
  761.                                             string str = row.GetCell(j).StringCellValue;
  762.                                             if (str != null && str.Length > 0)
  763.                                             {
  764.                                                 dataRow[j] = str.ToString();
  765.                                             }
  766.                                             else
  767.                                             {
  768.                                                 dataRow[j] = default(string);
  769.                                             }
  770.                                             break;
  771.                                         case CellType.Numeric://数字
  772.                                             if (DateUtil.IsCellDateFormatted(row.GetCell(j)))//时间戳数字
  773.                                             {
  774.                                                 dataRow[j] = DateTime.FromOADate(row.GetCell(j).NumericCellValue);
  775.                                             }
  776.                                             else
  777.                                             {
  778.                                                 dataRow[j] = Convert.ToDouble(row.GetCell(j).NumericCellValue);
  779.                                             }
  780.                                             break;
  781.                                         case CellType.Boolean:
  782.                                             dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
  783.                                             break;
  784.                                         case CellType.Error:
  785.                                             dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
  786.                                             break;
  787.                                         case CellType.Formula://公式
  788.                                             switch (row.GetCell(j).CachedFormulaResultType)
  789.                                             {
  790.                                                 case CellType.String:
  791.                                                     string strFORMULA = row.GetCell(j).StringCellValue;
  792.                                                     if (strFORMULA != null && strFORMULA.Length > 0)
  793.                                                     {
  794.                                                         dataRow[j] = strFORMULA.ToString();
  795.                                                     }
  796.                                                     else
  797.                                                     {
  798.                                                         dataRow[j] = null;
  799.                                                     }
  800.                                                     break;
  801.                                                 case CellType.Numeric:
  802.                                                     dataRow[j] = Convert.ToString(row.GetCell(j).NumericCellValue);
  803.                                                     break;
  804.                                                 case CellType.Boolean:
  805.                                                     dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
  806.                                                     break;
  807.                                                 case CellType.Error:
  808.                                                     dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
  809.                                                     break;
  810.                                                 default:
  811.                                                     dataRow[j] = "";
  812.                                                     break;
  813.                                             }
  814.                                             break;
  815.                                         default:
  816.                                             dataRow[j] = "";
  817.                                             break;
  818.                                     }
  819.                                 }
  820.                             }
  821.                             catch (Exception exception)
  822.                             {
  823.                                 //loger.Error(exception.ToString());
  824.                             }
  825.                         }
  826.                         table.Rows.Add(dataRow);
  827.                     }
  828.                     catch (Exception exception)
  829.                     {
  830.                         //loger.Error(exception.ToString());
  831.                     }
  832.                 }
  833.             }
  834.             catch (Exception exception)
  835.             {
  836.                 //loger.Error(exception.ToString());
  837.             }
  838.             return table;
  839.         }
  840.         /// <summary>
  841.         /// DataTable 转换为List<T>对象集合
  842.         /// </summary>
  843.         /// <typeparam name="TResult">类型</typeparam>
  844.         /// <param name="dt">DataTable</param>
  845.         /// <returns></returns>
  846.         public static List<TResult> DataTableToList<TResult>(this DataTable dt) where TResult : class, new()
  847.         {
  848.             //创建一个属性的列表
  849.             List<PropertyInfo> prlist = new List<PropertyInfo>();
  850.             //获取TResult的类型实例  反射的入口
  851.             Type t = typeof(TResult);
  852.             //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表
  853.             Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });
  854.             //创建返回的集合
  855.             List<TResult> oblist = new List<TResult>();
  856.             foreach (DataRow row in dt.Rows)
  857.             {
  858.                 //创建TResult的实例
  859.                 TResult ob = new TResult();
  860.                 //找到对应的数据  并赋值
  861.                 prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });
  862.                 //放入到返回的集合中.
  863.                 oblist.Add(ob);
  864.             }
  865.             return oblist;
  866.         }
  867.         /// <summary>
  868.         /// DataTable转化为List集合
  869.         /// </summary>
  870.         /// <typeparam name="T">实体对象</typeparam>
  871.         /// <param name="dt">datatable表</param>
  872.         /// <param name="isStoreDB">是否存入数据库datetime字段,date字段没事,取出不用判断</param>
  873.         /// <returns>返回list集合</returns>
  874.         private static List<T> DataTableToList<T>(DataTable dt, bool isStoreDB = true)
  875.         {
  876.             List<T> list = new List<T>();
  877.             Type type = typeof(T);
  878.             //List<string> listColums = new List<string>();
  879.             PropertyInfo[] pArray = type.GetProperties(); //集合属性数组
  880.             foreach (DataRow row in dt.Rows)
  881.             {
  882.                 T entity = Activator.CreateInstance<T>(); //新建对象实例
  883.                 foreach (PropertyInfo p in pArray)
  884.                 {
  885.                     if (!dt.Columns.Contains(p.Name) || row[p.Name] == null || row[p.Name] == DBNull.Value)
  886.                     {
  887.                         continue;  //DataTable列中不存在集合属性或者字段内容为空则,跳出循环,进行下个循环   
  888.                     }
  889.                     if (isStoreDB && p.PropertyType == typeof(DateTime) && Convert.ToDateTime(row[p.Name]) < Convert.ToDateTime("1753-01-01"))
  890.                     {
  891.                         continue;
  892.                     }
  893.                     try
  894.                     {
  895.                         var obj = Convert.ChangeType(row[p.Name], p.PropertyType);//类型强转,将table字段类型转为集合字段类型  
  896.                         p.SetValue(entity, obj, null);
  897.                     }
  898.                     catch (Exception)
  899.                     {
  900.                         // throw;
  901.                     }            
  902.                 }
  903.                 list.Add(entity);
  904.             }
  905.             return list;
  906.         }
  907.         /// <summary>
  908.         /// DataSet 转换成List
  909.         /// </summary>
  910.         /// <typeparam name="T"></typeparam>
  911.         /// <param name="ds"></param>
  912.         /// <param name="tableIndext"></param>
  913.         /// <returns></returns>
  914.         private static List<T> DataTable2List<T>(DataTable dt)
  915.         {
  916.             //确认参数有效
  917.             if (dt == null || dt.Rows.Count <= 0)
  918.             {
  919.                 return null;
  920.             }
  921.             IList<T> list = new List<T>(); //实例化一个list
  922.                                            // 在这里写 获取T类型的所有公有属性。 注意这里仅仅是获取T类型的公有属性,不是公有方法,也不是公有字段,当然也不是私有属性
  923.             PropertyInfo[] tMembersAll = typeof(T).GetProperties();
  924.             for (int i = 0; i < dt.Rows.Count; i++)
  925.             {
  926.                 //创建泛型对象。为什么这里要创建一个泛型对象呢?是因为目前我不确定泛型的类型。
  927.                 T t = Activator.CreateInstance<T>();
  928.                 //获取t对象类型的所有公有属性。但是我不建议吧这条语句写在for循环里,因为没循环一次就要获取一次,占用资源,所以建议写在外面
  929.                 //PropertyInfo[] tMembersAll = t.GetType().GetProperties();
  930.                 for (int j = 0; j < dt.Columns.Count; j++)
  931.                 {
  932.                     //遍历tMembersAll
  933.                     foreach (PropertyInfo tMember in tMembersAll)
  934.                     {
  935.                         //取dt表中j列的名字,并把名字转换成大写的字母。整条代码的意思是:如果列名和属性名称相同时赋值
  936.                         if (dt.Columns[j].ColumnName.ToUpper().Equals(tMember.Name.ToUpper()))
  937.                         {
  938.                             //dt.Rows[i][j]表示取dt表里的第i行的第j列;DBNull是指数据库中当一个字段没有被设置值的时候的值,相当于数据库中的“空值”。
  939.                             if (dt.Rows[i][j] != DBNull.Value)
  940.                             {
  941.                                 //SetValue是指:将指定属性设置为指定值。 tMember是T泛型对象t的一个公有成员,整条代码的意思就是:将dt.Rows[i][j]赋值给t对象的tMember成员,参数详情请参照http://msdn.microsoft.com/zh-cn/library/3z2t396t(v=vs.100).aspx/html
  942.                                 tMember.SetValue(t, Convert.ToString(dt.Rows[i][j]), null);
  943.                             }
  944.                             else
  945.                             {
  946.                                 tMember.SetValue(t, null, null);
  947.                             }
  948.                             break;//注意这里的break是写在if语句里面的,意思就是说如果列名和属性名称相同并且已经赋值了,那么我就跳出foreach循环,进行j+1的下次循环
  949.                         }
  950.                     }
  951.                 }
  952.                 list.Add(t);
  953.             }
  954.             dt.Dispose();
  955.             return list.ToList();
  956.         }
  957.         /// <summary>
  958.         /// 读取Excel文件特定名字sheet的内容到List<T>对象集合
  959.         /// </summary>
  960.         /// <param name="strFileName">excel文件路径</param>
  961.         /// <param name="dir">excel列名和DataTable列名的对应字典</param>
  962.         /// <param name="SheetName">excel表名</param>
  963.         /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param>
  964.         /// <returns></returns>
  965.         public static List<T> ImportExceltoDt<T>(string strFileName, Dictionary<string, string> dir, string SheetName, int HeaderRowIndex = 0)
  966.         {
  967.             DataTable table = new DataTable();
  968.             using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
  969.             {
  970.                 if (file.Length > 0)
  971.                 {
  972.                     IWorkbook wb = WorkbookFactory.Create(file);
  973.                     ISheet isheet = wb.GetSheet(SheetName);
  974.                     table = ImportDt(isheet, HeaderRowIndex, dir);
  975.                     isheet = null;
  976.                 }
  977.             }
  978.             List<T> results = DataTableToList<T>(table);
  979.             table.Dispose();
  980.             return results;
  981.         }
  982.         /// <summary>
  983.         /// 读取Excel文件某一索引sheet的内容到DataTable
  984.         /// </summary>
  985.         /// <param name="strFileName">excel文件路径</param>
  986.         /// <param name="sheet">需要导出的sheet序号</param>
  987.         /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param>
  988.         /// <param name="dir">excel列名和DataTable列名的对应字典</param>
  989.         /// <returns></returns>
  990.         public static List<T> ImportExceltoDt<T>(string strFileName, Dictionary<string, string> dir, int HeaderRowIndex = 0, int SheetIndex = 0)
  991.         {
  992.             DataTable table = new DataTable();
  993.             using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
  994.             {
  995.                 if (file.Length > 0)
  996.                 {
  997.                     IWorkbook wb = WorkbookFactory.Create(file);
  998.                     ISheet isheet = wb.GetSheetAt(SheetIndex);
  999.                     table = ImportDt(isheet, HeaderRowIndex, dir);
  1000.                     isheet = null;
  1001.                 }
  1002.             }
  1003.             List<T> results = DataTableToList<T>(table);
  1004.             table.Dispose();
  1005.             return results;
  1006.         }
  1007.         #endregion
  1008.         /// <summary>
  1009.         /// 获取excel文件的sheet数目
  1010.         /// </summary>
  1011.         /// <param name="outputFile"></param>
  1012.         /// <returns></returns>
  1013.         public static int GetSheetNumber(string outputFile)
  1014.         {
  1015.             int number = 0;
  1016.             using (FileStream readfile = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Read))
  1017.             {
  1018.                 if (readfile.Length > 0)
  1019.                 {
  1020.                     IWorkbook wb = WorkbookFactory.Create(readfile);
  1021.                     number = wb.NumberOfSheets;
  1022.                 }
  1023.             }
  1024.             return number;
  1025.         }
  1026.         /// <summary>
  1027.         /// 判断内容是否是数字
  1028.         /// </summary>
  1029.         /// <param name="message"></param>
  1030.         /// <param name="result"></param>
  1031.         /// <returns></returns>
  1032.         public static bool isNumeric(String message, out double result)
  1033.         {
  1034.             Regex rex = new Regex(@"^[-]?\d+[.]?\d*$");
  1035.             result = -1;
  1036.             if (rex.IsMatch(message))
  1037.             {
  1038.                 result = double.Parse(message);
  1039.                 return true;
  1040.             }
  1041.             else
  1042.                 return false;
  1043.         }
  1044.         /// <summary>
  1045.         /// 验证导入的Excel是否有数据
  1046.         /// </summary>
  1047.         /// <param name="excelFileStream"></param>
  1048.         /// <returns></returns>
  1049.         public static bool HasData(Stream excelFileStream)
  1050.         {
  1051.             using (excelFileStream)
  1052.             {
  1053.                 IWorkbook workBook = new HSSFWorkbook(excelFileStream);
  1054.                 if (workBook.NumberOfSheets > 0)
  1055.                 {
  1056.                     ISheet sheet = workBook.GetSheetAt(0);
  1057.                     return sheet.PhysicalNumberOfRows > 0;
  1058.                 }
  1059.             }
  1060.             return false;
  1061.         }
  1062.     }
  1063.     /// <summary>
  1064.     /// 排序实现接口 不进行排序 根据添加顺序导出
  1065.     /// </summary>
  1066.     public class NoSort : IComparer
  1067.     {
  1068.         public int Compare(object x, object y)
  1069.         {
  1070.             return -1;
  1071.         }
  1072.     }
  1073. }
复制代码
三、调用

3.1、增加一个“keywords”模型类,用作导出
  1. public class keywords
  2. {
  3.     [Column("姓名")]
  4.     public string IllegalKeywords { get; set; }
  5. }
复制代码
3.2、添加一个控制器

3.3、编写导入导出的控制器代码

3.3.1、重写“Close”函数

在导出时,为了防止MemoryStream无法关闭从而报错,所以我们继承MemoryStream;代码如下:
  1. namespace WebApplication1    //命名空间依据自己的项目进行修改
  2. {
  3.     public class NpoiMemoryStream : MemoryStream
  4.     {
  5.         public NpoiMemoryStream()
  6.         {
  7.             AllowClose = true;
  8.         }
  9.         public bool AllowClose { get; set; }
  10.         public override void Close()
  11.         {
  12.             if (AllowClose)
  13.                 base.Close();
  14.         }
  15.     }
  16. }
复制代码
3.3.2、添加控制器代码
  1. /// <summary>
  2. /// 本地环境
  3. /// </summary>
  4. private IHostingEnvironment _hostingEnv;
  5. /// <summary>
  6. /// Excel导入的具体实现
  7. /// </summary>
  8. /// <returns></returns>
  9. public IActionResult import_excel()
  10. {
  11.     string filepath = _hostingEnv.WebRootPath + "/在线用户20230324.xlsx";//导入的文件地址路径,可动态传入
  12.     Dictionary<string, string> dir = new Dictionary<string, string>();//申明excel列名和DataTable列名的对应字典
  13.     dir.Add("IllegalKeywords","姓名");
  14.     List<keywords> keyWordsList = ExcelHelper.ImportExceltoDt<keywords>(filepath, dir,"Sheet1",0);
  15.     #region 将List动态添加至数据库
  16.     //……
  17.     #endregion
  18.     return Json(new { code = 200, msg = "导入成功" });
  19. }
  20. /// <summary>
  21. /// Excel导出的具体实现
  22. /// </summary>
  23. /// <returns></returns>
  24. public IActionResult export_excel()
  25. {
  26.     #region 添加测试数据
  27.     List<keywords> keys = new List<keywords>();
  28.     for (int i = 0; i < 6; i++)
  29.     {
  30.         keywords keyword = new keywords();
  31.         keyword.IllegalKeywords = "测试_" + i;
  32.         keys.Add(keyword);
  33.     }
  34.     #endregion
  35.     #region 实例化DataTable并进行赋值
  36.     DataTable dt = new DataTable();
  37.     dt = listToDataTable(keys);//List<T>对象集合转DataTable
  38.     #endregion
  39.     string filename = DateTime.Now.ToString("在线用户yyyyMMdd") + ".xlsx";
  40.     Dictionary<string, string> dir = new Dictionary<string, string>();
  41.     dir.Add("IllegalKeywords", "姓名");
  42.     XSSFWorkbook book= ExcelHelper.ExportExcel(dt,  dir);
  43.     dt.Dispose();//释放DataTable所占用的数据资源
  44.     NpoiMemoryStream ms = new NpoiMemoryStream();
  45.     ms.AllowClose = false;
  46.     book.Write(ms, true);
  47.     ms.Flush();
  48.     ms.Position = 0;
  49.     ms.Seek(0, SeekOrigin.Begin);
  50.     ms.AllowClose = true;
  51.     book.Dispose();//使用由XSSFWorkbook所占用的资源
  52.     return File(ms, "application/vnd.ms-excel", Path.GetFileName(filename));//进行浏览器下载
  53. }
复制代码
3.3.3、Excel导出效果


3.3.4、Excel导入效果

导入后的List再根据需求调用添加方法实现数据的添加


来源:https://www.cnblogs.com/lucasDC/archive/2023/09/17/17707810.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具