【C#工具類】用NPOI匯入Excel,親測可用

之前做項目匯入Excel一直都是用的這個方法:

引用的com组件:Microsoft.Office.Interop.Excel.dll   读取EXCEL文件 

然而,用戶發來這麼個截圖!

【C#工具類】用NPOI匯入Excel,親測可用_第1张图片

雖然這個防呆是我這邊寫的,但事實證明原來的方法還是存在侷限性,所以后續引入了NPOI的寫法,親測可用,于是留下點東西預防再度跳坑~

1.參考中加入如下三個dll

NPOI.dll
NPOI.OOXML.dll
NPOI.OpenXML4Net.dll

【C#工具類】用NPOI匯入Excel,親測可用_第2张图片

2.引入ExcelHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using System.IO;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Test
{
	public class ExcelHelper : IDisposable
	{
		private string fileName = null; //文件名
		private IWorkbook workbook = null;
		private FileStream fs = null;
		private bool disposed;

		public ExcelHelper(string fileName)
		{
			this.fileName = fileName;
			disposed = false;
		}

		/// 
		/// 将DataTable数据导入到excel中
		/// 
		/// 要导入的数据
		/// DataTable的列名是否要导入
		/// 要导入的excel的sheet的名称
		/// 导入数据行数(包含列名那一行)
		public int DataTableToExcel(DataTable data, string sheetName, bool isColumnWritten)
		{
			int i = 0;
			int j = 0;
			int count = 0;
			ISheet sheet = null;

			fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
			if (fileName.IndexOf(".xlsx") > 0) // 2007版本
				workbook = new XSSFWorkbook();
			else if (fileName.IndexOf(".xls") > 0) // 2003版本
				workbook = new HSSFWorkbook();

			try
			{
				if (workbook != null)
				{
					sheet = workbook.CreateSheet(sheetName);
				}
				else
				{
					return -1;
				}

				if (isColumnWritten == true) //写入DataTable的列名
				{
					IRow row = sheet.CreateRow(0);
					for (j = 0; j < data.Columns.Count; ++j)
					{
						row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
					}
					count = 1;
				}
				else
				{
					count = 0;
				}

				for (i = 0; i < data.Rows.Count; ++i)
				{
					IRow row = sheet.CreateRow(count);
					for (j = 0; j < data.Columns.Count; ++j)
					{
						row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
					}
					++count;
				}
				workbook.Write(fs); //写入到excel
				return count;
			}
			catch (Exception ex)
			{
				Console.WriteLine("Exception: " + ex.Message);
				return -1;
			}
		}

		/// 
		/// 将excel中的数据导入到DataTable中
		/// 
		/// excel工作薄sheet的名称
		/// 第一行是否是DataTable的列名
		/// 返回的DataTable
		public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)
		{
			ISheet sheet = null;
			DataTable data = new DataTable();
			int startRow = 0;
			try
			{
				fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
				if (fileName.IndexOf(".xlsx") > 0) // 2007版本
					workbook = new XSSFWorkbook(fs);
				else if (fileName.IndexOf(".xls") > 0) // 2003版本
					workbook = new HSSFWorkbook(fs);

				if (sheetName != null)
				{
					sheet = workbook.GetSheet(sheetName);
					if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
					{
						sheet = workbook.GetSheetAt(0);
					}
				}
				else
				{
					sheet = workbook.GetSheetAt(0);
				}
				if (sheet != null)
				{
					IRow firstRow = sheet.GetRow(0);
					int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数

					if (isFirstRowColumn)
					{
						for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
						{
							ICell cell = firstRow.GetCell(i);
							if (cell != null)
							{
								string cellValue = cell.StringCellValue;
								if (cellValue != null)
								{
									DataColumn column = new DataColumn(cellValue);
									data.Columns.Add(column);
								}
							}
						}
						startRow = sheet.FirstRowNum + 1;
					}
					else
					{
						startRow = sheet.FirstRowNum;
					}

					//最后一列的标号
					int rowCount = sheet.LastRowNum;
					for (int i = startRow; i <= rowCount; ++i)
					{
						IRow row = sheet.GetRow(i);
						if (row == null) continue; //没有数据的行默认是null       

						DataRow dataRow = data.NewRow();
						for (int j = row.FirstCellNum; j < cellCount; ++j)
						{
							if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
								dataRow[j] = row.GetCell(j).ToString();
						}
						data.Rows.Add(dataRow);
					}
				}

				return data;
			}
			catch (Exception ex)
			{
				Console.WriteLine("Exception: " + ex.Message);
				return null;
			}
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!this.disposed)
			{
				if (disposing)
				{
					if (fs != null)
						fs.Close();
				}

				fs = null;
				disposed = true;
			}
		}
	}
}

3.調用方法

ExcelHelper ImportExcel = new ExcelHelper(FilePath);
DataTable table = ImportExcel.ExcelToDataTable("", true);

附:上面說的那三個dll我在【資源】里有分享~

補充:本方法有一個坑筆者暫時還沒爬出來,即無法處理Excel中自定義的時間(7“月”3“日”)C#無法認定為有效的dateTime,目前是讓使用者規範填寫 Excel單元格 的時間 ,若后續有緣爬出來的話某陌會來補充的,也歡迎大家集思廣益一起來交流學習一下~

另:匯出EXCEL

最上面補一句:DataTable dt = new DataTable();  //建立数据表(空表)

正式調用:

new ExcelHelper("导出的文件名.xls").DataTableToExcel(dt, "sheet1", true);

你可能感兴趣的:(C#,c#,数据库)