传统的单行写入数据的方式面对行数超过2000行的数据会出现明显的数据衰竭,由于读取文件的时候是直接转换为数据表,故尝试在写入的时候直接写入数据表,经过测试后可以明显提升写入速度。

本代码段需要使用以下关联

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

本程序包括两个部分:

1.从List集合转换为Table

        public static DataTable ToDataTable<T>(IEnumerable<T> collection)
        {
            var props = typeof(T).GetProperties();
            var dt = new DataTable();
            dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name, p.PropertyType)).ToArray());
            if (collection.Count() > 0)
            {
                for (int i = 0; i < collection.Count(); i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (PropertyInfo pi in props)
                    {
                        object obj = pi.GetValue(collection.ElementAt(i), null);
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    dt.LoadDataRow(array, true);
                }
            }
            return dt;
        }

2.将Table写入excel表格

        public static void DataToExcel(DataTable SourceDataTable,string FilePath)
        {
            MemoryStream ms = new MemoryStream();

            try
            {
                using (SourceDataTable)
                {
                    String hz = Path.GetExtension(FilePath);
                    IWorkbook workbook;

                    if (hz.Equals(".xls")) //针对2003版本  
                        workbook = new HSSFWorkbook();
                    else
                        workbook = new XSSFWorkbook();

                    NPOI.SS.UserModel.IFont font = workbook.CreateFont();
                    font.FontHeightInPoints = 12;
                    font.FontName = "宋体";
                    ICellStyle cellStyle = workbook.CreateCellStyle();
                    cellStyle.SetFont(font);

                    ISheet sheet = workbook.CreateSheet();
                    IRow headerRow = sheet.CreateRow(0);

                    // handling header.
                    foreach (DataColumn column in SourceDataTable.Columns)
                    {
                        sheet.SetColumnWidth(column.Ordinal, 10 * 256);
                        sheet.SetDefaultColumnStyle(column.Ordinal, cellStyle);
                        headerRow.CreateCell(column.Ordinal).SetCellValue(column.Caption);
                    }

                    // handling value.
                    int rowIndex = 0;

                    foreach (DataRow row in SourceDataTable.Rows)
                    {
                        IRow dataRow = sheet.CreateRow(rowIndex);
                        dataRow.RowStyle = cellStyle;
                        foreach (DataColumn column in SourceDataTable.Columns)
                        {
                            dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
                        }

                        rowIndex++;
                    }

                    workbook.Write(ms);
                    ms.Flush();
                    ms.Position = 0;
                }

                File.Delete(FilePath);

                using (FileStream fs = new FileStream(FilePath, FileMode.Create, FileAccess.Write))
                {
                    byte[] data = ms.ToArray();

                    fs.Write(data, 0, data.Length);
                    fs.Flush();
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

这么写可以一次性冲入大量数据而不用担心写入降速问题,但是缺点是无法使用源格式。后期将尝试调整。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐