• ExcelDataReader插件的使用


    NPOI插件的弊端

    刚来公司的时候公司软件导入导出操作都使用微软的office组件来实现,大家应该都知道这个组件有很大的弊端,就是运行主机上面必须安装office组件才可进行使用,不然无法进行导入导出操作,之前公司软件部门给的做法就是直接让客户安装Office就可以解决。

    我接手后知道这个弊端,将插件进行了替换,使用网上比较流行的NPOI插件,基本上很少出现关于软件导入导出数据的反馈。但由于之前的软件需求基本都是少量数据的导入导出,NPOI都可以满足,现在新需求要求导入导出超过40w行的数据,NPOI插件就暴露出来弊端,在数据少的时候使用.xlsx的XFFSWorkbook类就可以实现,但是数据量超过某一个阀值,XFFSWorkbook就出现了异常,爆出内存溢出的消息,而且声明和访问时速度特别慢,感觉是组件内部在处理大数据文件时存在问题。

    在网上查找发现NPOI对于大数据的处理有一个SXSSFWorkbook,它是NPOI专门来处理大数据文件的,我在使用过程中,当写入时,没问题可以使用,但是效率方面很差。可是在读取时,根本无法使用,因为它在使用过程中必须声明XFFWorkbook才可以,可是声明它的话就会遇到内存溢出问题。网上还有说直接使用xml形式来读取,但是xml格式需要自己去定义和解析,特别麻烦,故没有采用。

    //声明处理.xlsx文件的方法(小文件)
    IWorkbook workbook=new XSSFWorkbook();
    
    //声明处理.xlsx文件的方法(大文件)
    IWorkbook workbook=new XSSFWorkbook();
    IWorkbook wb=new SXSSFWorkbook(workbook);
    

    ExcelDataReader插件

    在处理读取.xlsx文件时,在nuget中发现了ExcelDataReader插件,在做了demo后,对于40w行的读取很方便,而且速度特别快。推荐大家使用。

                FileStream fs = null;
                IExcelDataReader excelReader = null;
                try
                {
                    fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                    excelReader = ExcelReaderFactory.CreateOpenXmlReader(fs);
                    int readIndex = 0;
                    int rowCount = excelReader.RowCount;                                                        //所有的行                
                    DataRow dr;
                    object tempValue;
    
                    while (excelReader.Read())
                    {
                        dr = data.NewRow();
    
                        if (readIndex == startReadRowCount)
                        {
                            ++readIndex;
                            continue;
                        }
                        
                        //读取Excel中的头文件信息
                        if (readIndex <startReadRowCount)
                        {
                            dr[0] = excelReader.GetValue(0).ToString();
                            tempValue = excelReader.GetValue(1);
                            if (tempValue==null)
                            {
                                dr[1] = DBNull.Value;
                            }
                            else
                            {
                                dr[1] = excelReader.GetValue(1).ToString();
                            }
                            
                            dr[2] = DBNull.Value;
                            dr[3] = DBNull.Value;
                            dr[4] = DBNull.Value;
                            dr[5] = DBNull.Value;
                            dr[6] = DBNull.Value;
                        }
                        else
                        {
                            dr[0] = excelReader.GetValue(0).ToString();
                            dr[1] = excelReader.GetValue(1).ToString();
                            dr[2] = Convert.ToDouble(excelReader.GetValue(2));
    
                            tempValue = excelReader.GetValue(3);
                            if (tempValue == null)
                            {
                                dr[3] = DBNull.Value;
                            }
                            else
                            {
                                dr[3] = Convert.ToDouble(excelReader.GetValue(3));
                            }
                            dr[4] = Convert.ToDouble(excelReader.GetValue(4));
                            dr[5] = Convert.ToDouble(excelReader.GetValue(5));
                            dr[6] = Convert.ToDouble(excelReader.GetValue(6));
                        }
                        data.Rows.Add(dr);
                        if (worker.CancellationPending)  // 如果用户取消则跳出处理数据代码 
                        {
                            e.Cancel = true;
                            break;
                        }
                        worker.ReportProgress(readIndex * 100 / rowCount);//加载进度条 
                        ++readIndex;
                    }
                    fs.Close();
                    fs.Dispose();
                    excelReader.Close();
                    excelReader.Dispose();
                    return data;
                }
                catch (Exception ex)
                {
                    if (worker.CancellationPending)  // 如果用户取消则跳出处理数据代码 
                    {
                        e.Cancel = true;
                    }
    
                    if (fs != null)
                    {
                        fs.Close();
                        fs.Dispose();
                    }
    
                    if (excelReader != null)
                    {
                        excelReader.Close();
                        excelReader.Dispose();
                    }
                    throw new Exception("" + ex.Message);
                }
    

    插件下载地址:
    https://www.nuget.org/packages/ExcelDataReader/3.0.0

    讲述工作、生活中的日常与感悟。
    作者:阿辉
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
    微信公众号:Andy阿辉
  • 相关阅读:
    vue的单向数据流
    vue的组件基础
    vue v-for的数组改变导致页面不渲染解决方法
    Binary Heap
    Types of Binary Tree
    Merge Sort
    Master Theorem
    Insertion Sort
    Amazon Redshift and Massively Parellel Processing
    Bubble Sort
  • 原文地址:https://www.cnblogs.com/netxiaohui/p/14696773.html
Copyright © 2020-2023  润新知