NPOI读取Excel

    游戏开发中免不了读取游戏配表,策划也通常会配置Excel或csv表。但游戏程序直接读取这样的表通常不是个好想法,尤其对于前端。如果把文件内容读取出来,接下来就可以为所欲为了,比如转成xml,json或自定义格式等等。

    接下来说的是读取excel表数据。公司使用的是vba,乍看666啊,但是真心慢啊,还有乱码问题(这个网上有介绍解决方法,但也比较蛋疼),于是就用com组件(添加 Microsoft.Office.Interop.Excel.dll引用)方式写了一个,速度提高了一倍(不要被网上大多数说的骗了,说此方式慢,实际上取数据时用object[,] cells = (object[,])worksheet.UsedRange.Value;var value = cells[row, column].ToString();这个操作,速度堪比oledb(Microsoft.Jet.OLEDB)方式的。至于oledb方式,暂不考虑,还要安装oledb驱动,当时尝试时竟然发现自己都没有安装),乱码问题也一并解决,后来公司不让用破解版office了(至于为何不用正版,你懂的),全部卸载安装wps,wps vba一堆问题,普通版不带vba,弄好了vba,update下来的文件里vba程序竟然没有了,无语了。于是转向了NPOI(速度再次提高一倍,如果使用任务Task,速度还可以再提高一倍,天下武功唯快不破,唔哈哈哈。。。)。下面是使用开源项目NPOI读取excel的示例。

    NPOI可以在此下载https://archive.codeplex.com/?p=npoi

using System;
using System.Collections.Generic;
using NPOI.SS.UserModel;
using System.Diagnostics;
using System.IO;

namespace ExcelTool
{
	public static class NPOIExcelHelper
	{
		/// 
		/// open excel workbook(工作簿) 
		/// 
		/// 文件路径
		/// 
		public static IWorkbook OpenWorkbook(string path)
		{
			FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Write);
			NPOI.SS.UserModel.IWorkbook workbook = WorkbookFactory.Create(fileStream);
			//var ext = System.IO.Path.GetExtension(path);
			//if (ext == ".xls")
			//	workbook = new NPOI.HSSF.UserModel.HSSFWorkbook(fileStream);
			//else if (ext == ".xlsx")
			//	workbook = new NPOI.XSSF.UserModel.XSSFWorkbook(fileStream);
			//else
			//{ }
			return workbook;
		}
		/// 
		/// search first or default excel worksheet whose name is started with pattern(在工作簿中查找以pattern开头的工作表)
		/// 
		/// 要查找的工作簿
		/// 指定开头字符串
		/// 
		public static ISheet FirstOrDefaultWorksheetNameStartWith(IWorkbook workbook, string pattern)
		{
			NPOI.SS.UserModel.ISheet worksheet = null;
			var length = workbook.NumberOfSheets;
			for (int i = 0; i < length; i++)
			{
				worksheet = workbook.GetSheetAt(i);
				if (worksheet.SheetName.StartsWith(pattern))
					break;
				worksheet = null;
			}
			return worksheet;
		}
		/// 
		/// read excel worksheet
		/// 
		/// 要读取的工作表
		/// 指定读取多少行
		/// 指定读取多少列
		/// 通常前3行是:注释,字段名和字段类型,如果注释全部不填,该行也应该读取
		/// 
		public static List ReadLines(ISheet worksheet, int rows = 0, int columns = 0, int startIndex = 3)
		{
			if (rows <= 0)
				rows = worksheet.LastRowNum + 1;
			else
				rows = Math.Min(rows, worksheet.LastRowNum + 1);
			if (rows == 0)
				return new List();

			int rownum = 0;
			IRow row = worksheet.GetRow(rownum);
			if (columns <= 0)
				columns = row.LastCellNum + 1;
			else
				columns = Math.Min(columns, row.LastCellNum + 1);
			//List<>的每一个元素是一行数据,string[]的每一个元素是对应单元格的string值
			List lines = new List(rows);
			while (rownum < rows)
			{
				if (row != null)
				{
					bool add = false;
					var line = new string[columns];
					for (int i = 0; i < columns; i++)
					{
						var cell = row.GetCell(i);
						if (cell != null)
						{
							if (cell.CellType != CellType.Formula)
								line[i] = cell.ToString().Trim();
							else
							{
								if (cell.CachedFormulaResultType == CellType.Numeric)
									line[i] = cell.NumericCellValue.ToString();
								else if (cell.CachedFormulaResultType == CellType.String)
									line[i] = cell.StringCellValue.Trim();
								else if (cell.CachedFormulaResultType == CellType.Boolean)
									line[i] = cell.BooleanCellValue.ToString();
							}
						}
						else
						{
							line[i] = null;
						}
						if (!string.IsNullOrEmpty(line[i]))
							add = true;
					}
					if (add)
						lines.Add(line);
				}
				else
				{
					if (rownum < startIndex)
					{
						var line = new string[columns];
						lines.Add(line);
					}
				}
				rownum++;
				row = worksheet.GetRow(rownum);
			}
			return lines;
		}
		/// 
		/// close excel workbook
		/// 
		/// 
		public static void CloseWorkbook(IWorkbook workbook)
		{
			workbook.Close();
		}
	}
}

    测试:

using System;
using System.Collections.Generic;
using NPOI.SS.UserModel;
using System.Diagnostics;

namespace ExcelTool
{
	partial class Program
	{
        static void main(string[] args)
        {
            var path = "E:/test.xlsx";
            testNPOI(path);
        }
		static void testNPOI(string path)
		{
			Stopwatch watch = new Stopwatch();
			watch.Start();
			var workbook = helper.OpenWorkbook(path);
			watch.Stop();
			Console.WriteLine("open finished:{0} ms elapsed", watch.ElapsedMilliseconds);
			var worksheet = NPOIExcelHelper.FirstOrDefaultWorksheetNameStartWith(workbook, "@");
			watch.Restart();
			var lines = NPOIExcelHelper.ReadLines(worksheet);
			watch.Stop();
			Console.WriteLine("read finished:{0} ms elapsed", watch.ElapsedMilliseconds);
			NPOIExcelHelper.CloseWorkbook(workbook);
		}
	}
}

 

你可能感兴趣的:(tools)