Импорт файла Excel в БД (отнимает много времени) - PullRequest
0 голосов
/ 09 мая 2019

Я использую MVC5 и импортирую файл Excel с помощью epplus в базу данных sql.Тем не менее, я могу импортировать файлы, которые меньше по размеру, например, менее 1000 КБ, но любой размер файла больше, чем это занимает часы, чтобы импортировать.Я ищу эффективный способ импортировать мой файл 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 голосов
/ 09 мая 2019

Вероятно, вставка в базу данных замедляет вас. Используйте 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);
0 голосов
/ 10 мая 2019

Я использую импорт в моем проекте, как показано ниже:

  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);
        }     
   } 

Теперь вы можете сохранить данные в базе данных.

0 голосов
/ 09 мая 2019

Я бы рекомендовал использовать библиотеку 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)
    {
    }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...