将excel文件导入db(花费很多时间)

时间:2019-05-09 12:52:31

标签: c# asp.net-mvc-5 epplus import-from-excel

我正在使用MVC5,并且正在使用epplus将excel文件导入sql数据库。但是,我能够导入较小的文件,例如小于1000kb,但是任何较大的文件,则要花费数小时才能导入。我正在寻找一种更快地导入excel文件的有效方法

public ActionResult Application(FormCollection formCollection)
    {
        var usersList = new List<bomApplicationImportTgt>();
        if (Request != null)
        {
            HttpPostedFileBase file = Request.Files["UploadedFile"];
            if ((file != null) && (file.ContentLength > 0) && !string.IsNullOrEmpty(file.FileName))
            {
                string fileName = file.FileName;
                string fileContentType = file.ContentType;
                byte[] fileBytes = new byte[file.ContentLength];
                var data = file.InputStream.Read(fileBytes, 0, Convert.ToInt32(file.ContentLength));
                using (var package = new ExcelPackage(file.InputStream))
                {
                    var currentSheet = package.Workbook.Worksheets;
                    var workSheet = currentSheet.First();
                    var noOfCol = workSheet.Dimension.End.Column;
                    var noOfRow = workSheet.Dimension.End.Row;
                    for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
                    {
                        var user = new bomApplicationImportTgt();
                        user.date = Convert.ToDateTime(workSheet.Cells[rowIterator, 1].Value);
                        user.Description = workSheet.Cells[rowIterator, 2].Value?.ToString();
                        user.SequenceNumber = Convert.ToInt32(workSheet.Cells[rowIterator, 3].Value);
                        user.PartNumber = workSheet.Cells[rowIterator, 4].Value?.ToString();
                        user.PartsName = workSheet.Cells[rowIterator, 5].Value?.ToString();
                        user.SP = workSheet.Cells[rowIterator, 6].Value?.ToString();
                        user.INT = workSheet.Cells[rowIterator, 7].Value?.ToString();
                        user.SN = workSheet.Cells[rowIterator, 8].Value?.ToString();
                        user.SZ = workSheet.Cells[rowIterator, 9].Value?.ToString();
                        user.C = workSheet.Cells[rowIterator, 10].Value?.ToString();
                        user.E_F = workSheet.Cells[rowIterator, 11].Value?.ToString();
                        user.Block = workSheet.Cells[rowIterator, 12].Value?.ToString();
                        user.SEC = workSheet.Cells[rowIterator, 13].Value?.ToString();
                        user.Item = workSheet.Cells[rowIterator, 14].Value?.ToString();
                        user.SUF = workSheet.Cells[rowIterator, 15].Value?.ToString();
                        user.Model = workSheet.Cells[rowIterator, 16].Value?.ToString();
                        user.M_E_F = workSheet.Cells[rowIterator, 17].Value?.ToString();
                        user.OP = workSheet.Cells[rowIterator, 18].Value?.ToString();
                        user.Type = workSheet.Cells[rowIterator, 19].Value?.ToString();
                        user.Quantity = workSheet.Cells[rowIterator, 20].Value?.ToString();
                        user.PLGRPCD = workSheet.Cells[rowIterator, 21].Value?.ToString();
                        user.PL1 = workSheet.Cells[rowIterator, 22].Value?.ToString();
                        user.ATC1 = workSheet.Cells[rowIterator, 23].Value?.ToString();
                        user.PL2 = workSheet.Cells[rowIterator, 24].Value?.ToString();
                        user.ATC2 = workSheet.Cells[rowIterator, 25].Value?.ToString();
                        user.PL3 = workSheet.Cells[rowIterator, 26].Value?.ToString();
                        user.ATC3 = workSheet.Cells[rowIterator, 27].Value?.ToString();
                        user.Plant = workSheet.Cells[rowIterator, 28].Value?.ToString();
                        user.SHR = workSheet.Cells[rowIterator, 29].Value?.ToString();
                        user.DC_Number = workSheet.Cells[rowIterator, 30].Value?.ToString();
                        user.FileName = fileName;
                        usersList.Add(user);
                    }
                }
            }
        }
        using (Dev_Purchasing_New_ModelEntities excelImportDBEntities = new Dev_Purchasing_New_ModelEntities())
        {
            foreach (var item in usersList)
            {
                excelImportDBEntities.bomApplicationImportTgts.Add(item);
            }
            excelImportDBEntities.SaveChanges();
        }
        return View("Application");
    }

3 个答案:

答案 0 :(得分:0)

我建议使用ExcelDataReader库,您可以通过Nuget添加它。在模型上,您只需要一个字节数组来保存电子表格数据和电子表格的路径。要添加它,请右键单击您的解决方案,然后选择“管理Nuget程序包”。然后搜索ExcelDataReader并安装它。

这是您要上传的模型:

public class SpreadsheetUploadModel
{
public byte[] Payload {get; set;}
public string FileName {get; set;}
}

这是您采取行动的基本思路,我不确定那里是否有回报。

    public IActionResult UploadSpreadsheet(SpreadsheetUploadModel mySheet)
    {
        IExcelDataReader rdr = null;
                    try
                    {
                            using (MemoryStream ms = new MemoryStream(mySheet.Payload)) //Payload is the byte array
                            {
                                ms.Position = 0;
                                string ext = Path.GetExtension(mySheet.FileName); //filename is the filename

                                switch (ext)
                                {
                                    case ".xls": //Old style (2003 or less)
                                        rdr = ExcelReaderFactory.CreateBinaryReader(ms);
                                        break;
                                    case ".xlsx": //New style (2007 or higher)
                                        rdr = ExcelReaderFactory.CreateOpenXmlReader(ms);
                                        break;
                                    default:
                                        throw new ArgumentOutOfRangeException(String.Format("File extension {0} is not recognized as valid", ext));
                                }

                                using (DataSet ds = rdr.AsDataSet())
                                {
                                    int rowNumber = 2;
                                    DataTable dt = ds.Tables[0];
                                    DataView dv = ds.DefaultViewManager.CreateDataView(ds.Tables[0]);

                                    foreach (DataRow row in rows)
                                    { //... logic in here - you can iterate the rows which will map the spreadsheet rows, so you can insert each row individually, or build a different model that your database function is expecting, or whatever else you're trying to do ... 
}
                                 }
                            }
    }
    catch(Exception ex)
    {
    }

    }

答案 1 :(得分:0)

可能是插入数据库会使您减速。使用SqlBulkCopy可以加快处理速度。 (您需要为FastMember引用对ObjectReader的引用)

public class BulkWriter
{
        private static readonly ConcurrentDictionary<Type, SqlBulkCopyColumnMapping[]> ColumnMapping =
            new ConcurrentDictionary<Type, SqlBulkCopyColumnMapping[]>();

        public async Task InsertAsync<T>(IEnumerable<T> items, string tableName, SqlConnection connection,
            CancellationToken cancellationToken)
        {
            using (var bulk = new SqlBulkCopy(connection))
            using (var reader = ObjectReader.Create(items))
            {
                bulk.DestinationTableName = tableName;
                foreach (var colMap in GetColumnMappings<T>())
                    bulk.ColumnMappings.Add(colMap);
                await bulk.WriteToServerAsync(reader, cancellationToken);
            }
        }

        private static IEnumerable<SqlBulkCopyColumnMapping> GetColumnMappings<T>() =>
            ColumnMapping.GetOrAdd(typeof(T),
                type => 
                    type.GetProperties()
                        .Select(p => new SqlBulkCopyColumnMapping(p.Name, p.Name)).ToArray());
}

用法:

await new BulkWriter().InsertAsync(usersList, "TheNameOfTheTable", excelImportDBEntities.Database.Connection, CancellationToken.None);

答案 2 :(得分:0)

我在项目中使用“导入”,如下所示:

  using Excel;
  var importFile = Request.Files["files"];
  if (importFile.ContentLength == 0)
  {
       ViewBag.errorFileMessage = "Please select file";
       return View();
  }
  Stream stream = importFile.InputStream;
  IExcelDataReader reader = null;
  reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
  reader.IsFirstRowAsColumnNames = true;
  DataSet result = reader.AsDataSet();
  DataTable dataRecords = new DataTable();
  //You can also remove empty rows 
  if (result.Tables.Count > 0)
  {
      dataRecords = result.Tables[0];
      for (int i = dataRecords.Rows.Count - 1; i >= 0; i--)
      {
          if (dataRecords.Rows[i][0] == DBNull.Value)
          {
              dataRecords.Rows[i].Delete();
          }
          dataRecords.AcceptChanges();
      }
   }
   if (dataRecords.Rows.Count > 0)
   {
        List<MyExcelListModel> reqData = new List<MyExcelListModel>();
        foreach (DataRow row in dataRecords.Rows)
        {
            MyExcelModel exceldata = new MyExcelModel();
            exceldata.Name= row[0].ToString();
            //Add according to your requirements
            reqData.Add(exceldata);
        }     
   } 

现在您可以将数据保存到数据库中。