我正在使用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");
}
答案 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);
}
}
现在您可以将数据保存到数据库中。