EXECL导入(检查服务器版本.包括NPOI方式导入.可以通过配置文件信息导入EXECL)代码记录下.

 在工作中很多要把EXECL的数据取出来的情况,因此,写一个相对通用的这种功能类很有必要.我因为当时只考虑了引用MS的EXECL类的情况,所以后面加入NPOI时这个类就有点显乱了,因为已经有人在用了,只能以后考虑修改了.MS的因为DLL的版本问题实在是个大麻烦,所以MS的EXECL类会全部用反射来调用.

1.一个辅助类.主要用于属性名与EXECL栏位的对应.

public class ColumnIndexProperty
{
    public int Index { get; set; }
    public string PropertyName { get; set; }
    public PropertyInfo Property { get; set; }
    public string SIndex
    {
        get
        {
            if (Index >= 1 && Index <= 702)
            {
                string result = string.Empty;
                int decade = Index / 26;
                int units = Index % 26;
                if (decade != 0)
                    result += AsciiIntToString(decade + 64);
                result += AsciiIntToString(units + 64);
                return result;
            }
            else
            {
                throw new Exception("EXECL的栏位要求在1-702之间.");
            }
        }
        set
        {
            value = value.ToUpper();
            char[] chars = value.ToCharArray();
            if (chars.Length == 1)
            {
                Index = AsciiStringToInt(value) - 64;
            }
            else if (chars.Length == 2)
            {
                int decade = AsciiStringToInt(chars[0].ToString()) - 64;
                int units = AsciiStringToInt(chars[1].ToString()) - 64;
                Index = decade * 26 + units;
            }
            else
            {
                throw new Exception("EXECL的栏位要求在A-ZZ之间.");
            }
        }
    }
    private string AsciiIntToString(int ascii)
    {
        System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
        byte[] byteArray = new byte[] { (byte)ascii };
        return asciiEncoding.GetString(byteArray);
    }
    private int AsciiStringToInt(String ch)
    {
        System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
        return asciiEncoding.GetBytes(ch)[0];
    }
}

2. 主要导入代码.

public class ReadExecl
{
    static ReadExecl()
    {
        //
        //TODO: 在此处添加构造函数逻辑
        //
    }
    public ReadExecl()
    {
        Top = 1;
        workIndex = 1;
        IsNopi = true;
        NotIndexs = new List<int>().ToArray();
        Cps = new List<ColumnIndexProperty>();
    }

    #region "基本属性设置"
    //设置要开始读取的行数    
    public int Top { get; set; }
    //导入方式
    public bool IsNopi { get; set; }
    //这个属性现暂时无用,因为读取列会从Cps里读取的.
    public int Left { get; set; }
    //设置栏位的序列与对应属性的对应
    public List<ColumnIndexProperty> Cps { get; set; }
    //文件名
    private string filePath;
    public string FilePath
    {
        get
        {
            return filePath;
        }
        set
        {
            double version = 0;
            if (!File.Exists(value))
            {
                throw new Exception("路径错误,请仔细检察.");
            }
            string protyery = value.Substring(value.LastIndexOf('.') + 1);
            if (protyery.ToUpper() != "XLS" && protyery.ToUpper() != "XLSX")
            {
                File.Delete(value);
                throw new Exception("不支持的文件格式.");
            }
            if (!IsNopi)
            {
                double.TryParse(Version, out version);
                if (version <= 11 && protyery.ToUpper() == "XLSX")
                {
                    File.Delete(value);
                    throw new Exception("文件版本格式过高,请升级服务器上的EXECL版本或降低EXECL文件版本.");
                }
            }
            filePath = value;
        }
    }
    //在EXECL上的第几张表里
    private int workIndex;
    public int WorksheetIndex
    {
        get
        {
            if (workIndex == 0)
                return 1;
            return workIndex;
        }
        set
        {
            //EXECL的起头并不是如C#等编程语言里的0开头,全是以1开头,页面数,行数,列数等
            if (value < 1)
                throw new Exception("不能少于1");
            workIndex = value;
        }
    }
    //设置那些行不能为空
    public string NotNull
    {
        set
        {
            string[] ns = value.Split(',');
            List<int> ls = new List<int>();
            foreach (var n in ns)
            {
                int result = 0;
                if (int.TryParse(n, out result))
                {
                    ls.Add(result);
                }
                else
                {
                    ColumnIndexProperty p = new ColumnIndexProperty() { SIndex = n };
                    ls.Add(p.Index);
                }
            }
            NotIndexs = ls.Distinct().ToArray();
        }
    }
    //设置导入文件的地方信息
    public CultureInfo CultureInfo
    {
        get;
        set;
    }
    #endregion

    #region "一些帮助属性"
    public string ErrorMassage
    {
        get;
        set;
    }
    public int[] NotIndexs { get; set; }

    public string[] NotSIndex
    {
        get
        {
            List<string> ls = new List<string>();
            foreach (var index in NotIndexs)
            {
                ColumnIndexProperty p = new ColumnIndexProperty() { Index = index };
                ls.Add(p.SIndex);
            }
            return ls.ToArray();
        }
        set
        {
            List<int> ls = new List<int>();
            foreach (var sindex in value)
            {
                ColumnIndexProperty p = new ColumnIndexProperty() { SIndex = sindex };
                ls.Add(p.Index);
            }
            NotIndexs = ls.ToArray();
        }
    }
    #endregion

    #region "类私有的帮助函数"
    private string pathDate()
    {
        string fileName = FilePath.Substring(FilePath.LastIndexOf(@"\") + 1);
        string Path = FilePath.Substring(0, FilePath.LastIndexOf(@"\"));
        string[] bs = fileName.Split('.');
        fileName = bs[0] + DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
        return Path + @"\" + fileName;
    }
    /// <summary>
    /// 把PropertyInfo和实体T的属性对应
    /// </summary>
    /// <typeparam name="T"></typeparam>
    private void FullColumnIndexProperty<T>()
    {
        //得到对应实体的属性
        PropertyInfo[] ps = typeof(T).GetProperties();
        //把属性与对应EXECL上的表栏位对应起来     
        foreach (var cp in Cps)
        {
            //把属性与栏位对应上.没有对应上会直接抛出异常
            cp.Property = ps.First(t => t.Name == cp.PropertyName);
        }
    }
    /// <summary>
    /// 杀掉相应的EXECL进程
    /// </summary>
    /// <param name="excel"></param>
    /// <param name="StartTime"></param>
    /// <param name="EndTime"></param>
    private void Kill(object excel, DateTime StartTime, DateTime EndTime)
    {
        if (excel == null)
        {
            return;
        }
        int hwnd = 0;
        try
        {
            hwnd = (int)excel.GetType().InvokeMember("Hwnd", BindingFlags.GetProperty, null, excel, null);
        }
        catch
        {
            hwnd = 0;
        }
        IntPtr t = new IntPtr(hwnd);
        int k = 0;
        GetWindowThreadProcessId(t, out k);
        if (k != 0)
        {
            Process f = Process.GetProcessById(k);
            f.Kill();
        }
        else
        {
            //这个方法如果同时有多个人处理EXECL就会出问题,可能关闭掉本不应该关闭掉的EXECL进程
            foreach (Process p in Process.GetProcesses().Where(
                p => p.ProcessName.StartsWith("EXCEL", StringComparison.OrdinalIgnoreCase)))
            {
                if (p.StartTime >= StartTime && p.StartTime <= EndTime)
                {
                    p.Kill();
                }
            }

        }


    }
    /// <summary>
    /// 把EXECL文件对应表的数据转换成TXT文件并返回对应TXT文件的路径
    /// </summary>
    /// <returns></returns>
    private string TransformFile()
    {
        string fileName = this.pathDate();
        DateTime StartTime = DateTime.Now;
        //打开EXECL       
        Type objExcelType = Type.GetTypeFromProgID("Excel.Application");
        if (objExcelType == null)
        {
            throw new Exception("没有安装EXECL.");
        }
        object objApp = Activator.CreateInstance(objExcelType);
        if (objApp == null)
        {
            throw new Exception("不能创建EXECL进程.");
        }
        DateTime EndTime = DateTime.Now;
        //获取Workbook集
        try
        {
            object objBooks = objApp.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, objApp, null);
            //第二个参数为0表示不更新任何链接
            object[] os = new object[]{FilePath, 0, Type.Missing, Type.Missing, Type.Missing,
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                Type.Missing, Type.Missing, Type.Missing, Type.Missing};
            objBooks.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, objBooks, os);
            object worksheets = objApp.GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, objApp, null);
            object sheet = objBooks.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, worksheets, new object[1] { workIndex });
            // Excel.XlFileFormat.xlUnicodeText 为42,保存为Unicode字符集的TXT文件
            object[] savas = new object[] { fileName, 42, Type.Missing, Type.Missing,
                false, false, 1, Type.Missing, Type.Missing, Type.Missing};

            sheet.GetType().InvokeMember("SaveAs", BindingFlags.InvokeMethod, null, sheet, savas);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(sheet);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheets);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(objBooks);
            objApp.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, objApp, null);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(objApp);
            GC.Collect();
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
        finally
        {
            Kill(objApp, StartTime, EndTime);
            //以免出现这个文件已经有个进程在用的异常(等待EXECL关闭)
            Thread currentThread = Thread.CurrentThread;
            currentThread.Join(500);
        }
        return fileName;
    }
    /// <summary>
    /// 把String类型的值转化成对应的类型
    /// </summary>
    /// <param name="value"></param>
    /// <param name="conversionType"></param>
    /// <returns></returns>
    private object ChangeTypeTo(string value, Type conversionType)
    {
        if (conversionType == null)
            throw new ArgumentNullException("conversionType");
        if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            if (string.IsNullOrEmpty(value))
                return null;
            NullableConverter nullableConverter = new NullableConverter(conversionType);
            conversionType = nullableConverter.UnderlyingType;
        }
        if (conversionType == typeof(Guid))
        {
            return new Guid(value);
        }
        else if (conversionType == typeof(int))
        {
            value = value.Replace(",", "");
            value = value.Trim(',', '"');
            if (string.IsNullOrEmpty(value))
                return 0;
            return int.Parse(value);
        }
        else if (conversionType == typeof(DateTime))
        {
            if (CultureInfo == null)
                return DateTime.Parse(value);
            else
                return DateTime.Parse(value, CultureInfo);
        }
        else if (conversionType == typeof(string))
        {
            return value;
        }
        return Convert.ChangeType(value, conversionType);
    }
    /// <summary>
    /// NOPI要转文件的转化
    /// </summary>
    /// <param name="cell"></param>
    /// <param name="conversionType"></param>
    /// <returns></returns>
    private object ChangeTypeTo(NPOI.SS.UserModel.Cell cell, Type conversionType)
    {
        if (conversionType == null)
            throw new ArgumentNullException("conversionType");
        if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            if (cell == null)
                return null;
            NullableConverter nullableConverter = new NullableConverter(conversionType);
            conversionType = nullableConverter.UnderlyingType;
        }
        if (conversionType == typeof(string) && (cell == null || string.IsNullOrEmpty(cell.ToString())))
            return null;
        if (conversionType == typeof(Guid))
        {
            return new Guid(cell.ToString());
        }
        else if (conversionType == typeof(DateTime))
        {
            if (cell.CellType == NPOI.SS.UserModel.CellType.NUMERIC)
                return cell.DateCellValue;
            else
            {
                if (CultureInfo == null)
                    return DateTime.Parse(cell.StringCellValue);
                else
                    return DateTime.Parse(cell.StringCellValue, CultureInfo);
            }
        }
        else if (cell.CellType == NPOI.SS.UserModel.CellType.NUMERIC)
        {
            return Convert.ChangeType(cell.NumericCellValue, conversionType);
        }
        else
        {
            return Convert.ChangeType(cell.StringCellValue, conversionType);
        }
    }

    #endregion

    #region "导出EXECL的数据"
    /// <summary>
    /// 设置好相关属性后取出EXECL的数据并转化成相应的类的对象
    /// </summary>
    /// <typeparam name="T">要得到数据的类型</typeparam>
    /// <returns>返回EXECL对应的对象集</returns>
    public List<T> GetExecl<T>() where T : new()
    {
        this.ErrorMassage = string.Empty;
        if (IsNopi)
            return GetNExecl<T>();
        else
            return GetLExecl<T>();
    }
    /// <summary>
    /// 设置好相关属性后取出EXECL的数据并转化成相应的类的对象
    /// </summary>
    /// <typeparam name="T">要得到数据的类型</typeparam>
    /// <param name="notIndexs">不能为空的栏位索引</param>
    /// <returns>返回EXECL对应的对象集</returns>
    public List<T> GetLExecl<T>() where T : new()
    {
        string file = TransformFile();
        List<T> data = new List<T>();
        StreamReader sr = new StreamReader(file);
        try
        {
            for (int i = 1; i < Top; i++)
            {
                sr.ReadLine();
            }
            //得到对应实体的属性
            FullColumnIndexProperty<T>();
            string line = string.Empty;
            int currentLine = Top - 1;
            int max = Cps.Max(p => p.Index);
            while ((line = sr.ReadLine()) != null)
            {
                currentLine++;
                string[] split = line.Split('\t');
                if (max > split.Count())
                    continue;
                bool result = true;
                foreach (int index in NotIndexs)
                {
                    if (index > 0 && string.IsNullOrEmpty(split[index - 1]))
                        result = false;
                }
                if (!result)
                    continue;
                T t = new T();
                foreach (var cp in Cps)
                {
                    try
                    {
                        string value = split[cp.Index - 1];
                        object va = ChangeTypeTo(value.Trim(), cp.Property.PropertyType);
                        cp.Property.SetValue(t, va, null);
                    }
                    catch (Exception e)
                    {
                        this.ErrorMassage += string.Format("Execl文件第{0}行第{1}栏有错误为:{2}<br>", currentLine, cp.SIndex, e.Message);
                        continue;
                    }
                }
                data.Add(t);
            }
            return data;
        }
        catch (Exception e)
        {
            this.ErrorMassage += e.Message + "<br>";
            return null;
        }
        finally
        {
            sr.Close();
            File.Delete(file);
        }
    }
    /// <summary>
    /// 通过NOPI的方式导入.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> GetNExecl<T>() where T : new()
    {
        //填入属性和栏位的关系        
        FullColumnIndexProperty<T>();
        List<T> data = new List<T>();
        Stream filestream = new FileStream(FilePath, FileMode.Open);
        //打开EXECL文件
        HSSFWorkbook workbook = new HSSFWorkbook(filestream);
        //打开对应的EXECL表
        var worksheet = workbook.GetSheetAt(WorksheetIndex - 1);
        int start = Top - 1;
        int end = worksheet.LastRowNum;
        //检查栏位是否为空
        Func<int, int, bool> IsNull = (row, col) =>
        {
            var cell = worksheet.GetRow(row).GetCell(col);
            return cell == null ||
                string.IsNullOrEmpty(cell.ToString());
        };
        //开始查找EXECL文件数据.
        for (int i = start; i <= end; i++)
        {
            bool result = true;
            foreach (int index in NotIndexs)
            {
                if (IsNull(i, index - 1))
                    result = false;
            }
            if (!result)
                continue;
            T t = new T();
            foreach (var cp in Cps)
            {
                try
                {
                    object value = this.ChangeTypeTo(worksheet.GetRow(i).GetCell(cp.Index - 1), cp.Property.PropertyType);
                    cp.Property.SetValue(t, value, null);
                }
                catch (Exception e)
                {
                    this.ErrorMassage += string.Format("Execl文件第{0}行第{1}栏有错误为:{2}<br>", i + 1, cp.SIndex, e.Message);
                    continue;
                }
            }
            data.Add(t);
        }
        return data;
    }
    #endregion

    #region "Execl信息帮助和获得"
    public List<int> ErrorLine { get; set; }

    [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
    public override string ToString()
    {
        string vell = "&nbsp;&nbsp;";
        string fileName = FilePath.Substring(FilePath.LastIndexOf(@"\") + 1);
        string message = string.Empty;
        //  message += "文件名:" + fileName + "." + vell;
        message += string.Format("读取当前文件的第{0}张表.{1}", this.workIndex, vell);
        message += string.Format("从第{0}行开始读入数据.{1}读取的栏位索引", Top, vell);
        foreach (var cp in Cps)
        {
            message += cp.SIndex.ToString() + "格式为";
            message += GetTypeInfo(cp.Property.PropertyType) + ",";
        }
        message = message.Substring(0, message.LastIndexOf(","));
        message += ".";
        if (NotIndexs.Length == 0 || NotIndexs[0] == 0)
            return message;
        message += vell + "以下栏位索引";
        foreach (var index in this.NotSIndex)
        {
            message += index + ",";
        }
        message = message.Substring(0, message.LastIndexOf(","));
        message += "不能为空.";
        return message;
    }
    public static string GetTypeInfo(Type type)
    {
        type = type.ChangeTypeTo();
        string result = "末知";
        if (type == typeof(Int32) || type == typeof(Int16) || type == typeof(Int64))
            result = "整数";
        else if (type == typeof(DateTime))
            result = "时间";
        else if (type == typeof(float) || type == typeof(decimal) || type == typeof(double))
            result = "精确数";
        else if (type == typeof(Guid))
            result = "GUID";
        else if (type == typeof(bool))
            result = "布尔值";
        else if (type == typeof(byte[]))
            result = "字符数组";
        else
            result = "字符串";
        return result;
    }
    public string Version
    {
        get
        {
            DateTime start = DateTime.Now;
            Type objExcelType = Type.GetTypeFromProgID("Excel.Application");
            if (objExcelType == null)
            {
                throw new Exception("没有安装EXECL.");
            }
            object objApp = Activator.CreateInstance(objExcelType);
            if (objApp == null)
            {
                throw new Exception("不能创建EXECL进程.");
            }
            DateTime end = DateTime.Now;
            string version = objApp.GetType().InvokeMember("Version", BindingFlags.GetProperty, null, objApp, null) as string;
            Kill(objApp, start, end);
            return version;
        }
    }
    #endregion

    #region "如果有配置文件,从配置文件取数据"
    /// <summary>
    /// 专用于读配置文件时给对应对象加上标识
    /// </summary>
    public string Name { get; set; }
    private static List<ReadExecl> readExecls;
    /// <summary>
    /// 读配置文件的信息
    /// </summary>
    private static void GetPageConfig()
    {
        //配置文件固定在应用程序的根目录并且文件名为ExeclDownFileConfig.xml
        string configPath = HttpContext.Current.Server.MapPath("~/") + "ExeclDownFileConfig.xml";
        if (!File.Exists(configPath))
            throw new Exception("没有对应的EXECL文件配置.");
        //加载XML文件.
        var xdoc = XDocument.Load(configPath);
        List<ReadExecl> res = new List<ReadExecl>();
        //浏览XML文件的节点.
        foreach (var a in xdoc.Descendants("ExeclFile"))
        {
            ReadExecl readexecl = new ReadExecl();
            if (a.Element("Name") != null)
                readexecl.Name = a.Element("Name").Value;
            if (a.Element("Top") != null)
                readexecl.Top = int.Parse(a.Element("Top").Value);
            if (a.Element("WorksheetIndex") != null)
                readexecl.WorksheetIndex = int.Parse(a.Element("WorksheetIndex").Value);
            if (a.Element("NotNull") != null)
                readexecl.NotNull = a.Element("NotNull").Value;
            if (a.Element("CultureInfo") != null)
                readexecl.CultureInfo = new CultureInfo(a.Element("CultureInfo").Value);
            if (a.Element("IsNopi") != null && a.Element("IsNopi").Value.ToUpper() != "TRUE")
                readexecl.IsNopi = false;
            if (a.Element("FilePath") != null)
                readexecl.FilePath = a.Element("FilePath").Value;
            foreach (var b in a.Element("ExeclColumns").Descendants("ExeclColumn"))
            {
                int i = 0;
                string index = b.Element("Index").Value;
                string propertyname = b.Element("Propertyname").Value;
                if (int.TryParse(index, out i))
                    readexecl.Cps.Add(new ColumnIndexProperty() { Index = i, PropertyName = propertyname });
                else
                    readexecl.Cps.Add(new ColumnIndexProperty() { SIndex = index, PropertyName = propertyname });
            }
            res.Add(readexecl);
        }
        readExecls = res;
    }
    /// <summary>
    /// 外部接口用于得到存储配置文件的信息
    /// </summary>
    public static List<ReadExecl> ReadExecls
    {
        get
        {
            if (readExecls == null)
            {
                GetPageConfig();
            }
            return readExecls;
        }
    }
    /// <summary>
    /// 根据对应对象的标识得到相应的对象
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static ReadExecl GetReadExecl(string name)
    {
        return ReadExecls.First(p => p.Name.ToUpper() == name.ToUpper());
    }
    #endregion
}

3.xml文件配置如下(ps:配置文件固定在应用程序的根目录并且文件名为ExeclDownFileConfig.xml)

<?xml version="1.0" encoding="utf-16"?>
<ReadExeclFile>
  <Project>PEM</Project>
  <ExeclFiles>
    <ExeclFile>
      <Name>TRP_CustomerOrder</Name>     
      <WorksheetIndex>1</WorksheetIndex>
      <Top>11</Top>
      <NotNull>1</NotNull>
      <ExeclColumns>
        <ExeclColumn>
          <Index>A</Index>
          <Propertyname>Serial</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>2</Index>
          <Propertyname>Customer</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>3</Index>
          <Propertyname>OrderNo</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>4</Index>
          <Propertyname>MachineType</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>5</Index>
          <Propertyname>ProductNO</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>G</Index>
          <Propertyname>Quantity</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>I</Index>
          <Propertyname>ReqDate</Propertyname>
        </ExeclColumn>
      </ExeclColumns>
      <IsNopi>True</IsNopi>
    </ExeclFile>
    <ExeclFile>
      <Name>TRP_Inventory</Name>      
      <WorksheetIndex>1</WorksheetIndex>
      <Top>4</Top>
      <NotNull>1</NotNull>
      <ExeclColumns>
        <ExeclColumn>
          <Index>1</Index>
          <Propertyname>TNumber</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>2</Index>
          <Propertyname>Description</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>11</Index>
          <Propertyname>StockNT360</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>12</Index>
          <Propertyname>StockUT360</Propertyname>
        </ExeclColumn>
      </ExeclColumns>
      <IsNopi>True</IsNopi>
    </ExeclFile>
    <ExeclFile>
      <Name>TRP_OpenPO</Name>
      <WorksheetIndex>1</WorksheetIndex>  
      <Top>2</Top>          
      <CultureInfo>fr-FR</CultureInfo>
      <ExeclColumns>
        <ExeclColumn>
          <Index>1</Index>
          <Propertyname>OrderNumber</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>3</Index>
          <Propertyname>OrederDate</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>7</Index>
          <Propertyname>TNumber</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>14</Index>
          <Propertyname>UM</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>37</Index>
          <Propertyname>OriginalOrderedAmount</Propertyname>
        </ExeclColumn>
      </ExeclColumns>
      <IsNopi>True</IsNopi>
    </ExeclFile>
    <ExeclFile>
      <Name>TRP_ProducingOrder</Name>
      <WorksheetIndex>1</WorksheetIndex>
      <Top>3</Top>
      <NotNull>G,14,16</NotNull>     
      <ExeclColumns>
        <ExeclColumn>
          <Index>1</Index>
          <Propertyname>Machine</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>7</Index>
          <Propertyname>PartNO</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>10</Index>
          <Propertyname>Serial</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>N</Index>
          <Propertyname>QtyUnfinished</Propertyname>
        </ExeclColumn>
        <ExeclColumn>
          <Index>P</Index>
          <Propertyname>PlannedOnMachineDate</Propertyname>
        </ExeclColumn>
      </ExeclColumns>
      <IsNopi>True</IsNopi>
    </ExeclFile>
  </ExeclFiles> 
</ReadExeclFile>

4.用法.

            //Exevl导入方式
            ReadExecl re = new ReadExecl();
            re.Top = 11;
            re.FilePath = fileName;
            re.WorksheetIndex = 4;
            re.Cps = new List<ColumnIndexProperty>(){
                new ColumnIndexProperty(){Index=1,PropertyName= "Serial"},
                new ColumnIndexProperty(){Index=2,PropertyName= "Customer"},
                new ColumnIndexProperty(){Index=3,PropertyName= "OrderNo"},
                new ColumnIndexProperty(){Index=4,PropertyName= "MachineType"} ,   
                new ColumnIndexProperty(){Index=5,PropertyName= "ProductNO"} ,
                new ColumnIndexProperty(){Index=6,PropertyName= "Quantity"} ,
                new ColumnIndexProperty(){Index=8,PropertyName= "ReqDate"} 
            };
            re.NotNull = "1";
            //配置文件导入方式
            ReadExecl re = ReadExecl.GetReadExecl("TRP_CustomerOrder");
            re.FilePath = fileName;
原文地址:https://www.cnblogs.com/zhouxin/p/1916022.html