import excel na novo z izpiso napak

This commit is contained in:
2026-02-28 12:25:39 +01:00
parent 3d4bb077cc
commit 1da4b1e751
5 changed files with 301 additions and 250 deletions

View File

@@ -48,31 +48,48 @@ namespace EveryThing.Pages.Projects
public string SelectedItems { get; set; }
public IActionResult OnGet(int idProject, int idProjectPart, string fileName)
public IActionResult OnGet(int idProject, int idProjectPart)
{
var user = _userManager.GetUserAsync(User).Result;
IdProject = idProject;
IdProjectPart = idProjectPart;
FileName = fileName;
var tmpList = typeof(Models.Project.ProjectPartItem).GetProperties()
.Where(x => x.GetCustomAttributes(true).Length > 0 && x.GetCustomAttributes(true).Any(y => y.GetType() == typeof(System.ComponentModel.DataAnnotations.DisplayAttribute)))
.Select(x => new
{
Name = x.Name,
Display = ((System.ComponentModel.DataAnnotations.DisplayAttribute)x.GetCustomAttributes(true).First(y => y.GetType() == typeof(System.ComponentModel.DataAnnotations.DisplayAttribute))).Name
}).ToList();
tmpList.Insert(0, new { Name = "", Display = "Ni izbrano" });
ViewData["ProjectPartItems"] = new SelectList(tmpList, "Name", "Display");
ExcelItems = new List<ExcelItem>();
var path = Path.Combine(_hostingEnvironment.WebRootPath, "Uploads", "TempExcelImport", fileName);
var xlWorkbook = new XLWorkbook(path);
//ONLY FIRST LIST
return Page();
}
public async Task<IActionResult> OnPostUpload(int idProject, int idProjectPart, List<IFormFile> postedFiles)
{
if (postedFiles == null
|| postedFiles.Count != 1)
{
return new JsonResult(new { successful = false, error = "Izberite eno datoteko." });
}
var path = Path.Combine(_hostingEnvironment.WebRootPath, "Uploads", "TempExcelImport");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
else
{
//Pocistimo mapo
foreach (var fileInfo in new DirectoryInfo(path).GetFiles("*.*"))
{
fileInfo.Delete();
}
}
var postedFile = postedFiles[0];
var fileName = postedFile.FileName;
await using (var stream = new FileStream(Path.Combine(path, fileName), FileMode.Create))
{
await postedFile.CopyToAsync(stream);
}
// Read excel headers
var excelItems = new List<ExcelItem>();
var filePath = Path.Combine(path, fileName);
var xlWorkbook = new XLWorkbook(filePath);
var worksheet = xlWorkbook.Worksheet(1);
int i = 1;
@@ -82,26 +99,36 @@ namespace EveryThing.Pages.Projects
int j = 1;
while (!row.Cell(j).IsEmpty())
{
var cellData = row.Cell(j).Value;
ExcelItems.Add(new ExcelItem
excelItems.Add(new ExcelItem
{
CellIndex = j,
Name = cellData.ToString(),
Name = row.Cell(j).Value.ToString(),
});
j++;
}
}
return Page();
// Build mapping options
var mappingOptions = typeof(Models.Project.ProjectPartItem).GetProperties()
.Where(x => x.GetCustomAttributes(true).Length > 0 && x.GetCustomAttributes(true).Any(y => y.GetType() == typeof(System.ComponentModel.DataAnnotations.DisplayAttribute)))
.Select(x => new
{
name = x.Name,
display = ((System.ComponentModel.DataAnnotations.DisplayAttribute)x.GetCustomAttributes(true).First(y => y.GetType() == typeof(System.ComponentModel.DataAnnotations.DisplayAttribute))).Name
}).ToList();
return new JsonResult(new { successful = true, fileName, excelItems, mappingOptions });
}
public async Task<IActionResult> OnPostAsync(string selectedItems)
public async Task<IActionResult> OnPostImport(string selectedItems, string fileName, int idProjectPart, int idProject)
{
if (selectedItems == "")
FileName = fileName;
IdProjectPart = idProjectPart;
IdProject = idProject;
if (string.IsNullOrEmpty(selectedItems))
{
return Page(); //TODO Error
return new JsonResult(new { successful = false, error = "Izberite vsaj eno polje." });
}
var user = _userManager.GetUserAsync(User).Result;
@@ -128,6 +155,73 @@ namespace EveryThing.Pages.Projects
//ONLY FIRST LIST
var worksheet = xlWorkbook.Worksheet(1);
// Build display name lookup for properties
var propertyDisplayNames = typeof(Models.Project.ProjectPartItem).GetProperties()
.Where(x => x.GetCustomAttributes(true).Any(y => y is System.ComponentModel.DataAnnotations.DisplayAttribute))
.ToDictionary(
x => x.Name,
x => ((System.ComponentModel.DataAnnotations.DisplayAttribute)x.GetCustomAttributes(true).First(y => y is System.ComponentModel.DataAnnotations.DisplayAttribute)).Name
);
// Validation pass - check all rows before importing
var errors = new List<object>();
int validationRow = 2; // Skip header
while (!worksheet.Row(validationRow).IsEmpty())
{
IXLRow row = worksheet.Row(validationRow);
// Check if all mapped cells in the row are empty
bool allEmpty = excelItems.All(ei =>
row.Cell(ei.CellIndex) == null || string.IsNullOrWhiteSpace(row.Cell(ei.CellIndex).Value.ToString()));
if (allEmpty)
{
errors.Add(new { row = validationRow, property = "-", value = "", message = "Vsa polja v vrstici so prazna." });
validationRow++;
continue;
}
foreach (var excelItem in excelItems)
{
if (row.Cell(excelItem.CellIndex) == null)
continue;
string value = row.Cell(excelItem.CellIndex).Value.ToString();
string displayName = propertyDisplayNames.ContainsKey(excelItem.Name) ? propertyDisplayNames[excelItem.Name] : excelItem.Name;
// Empty individual cells are allowed - skip validation
if (string.IsNullOrWhiteSpace(value))
continue;
if (excelItem.Name is "IdItemFk" or "IdMaterialFk" or "IdMaterialSupplierFk")
{
// These are text lookups, no type conversion needed
continue;
}
// Validate type conversion for other properties
var propertyInfo = typeof(Models.Project.ProjectPartItem).GetProperties().FirstOrDefault(x => x.Name == excelItem.Name);
if (propertyInfo != null)
{
try
{
var targetType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
Convert.ChangeType(value, targetType);
}
catch
{
errors.Add(new { row = validationRow, property = displayName, value, message = $"Ni mogoče pretvoriti v tip {propertyInfo.PropertyType.Name}." });
}
}
}
validationRow++;
}
if (errors.Count > 0)
{
return new JsonResult(new { successful = false, validationErrors = errors });
}
var insertedParts = _context.ProjectPartItems.Where(x => x.IdProjectPartFk == IdProjectPart);
var currentPositionNumber = insertedParts.Any()
@@ -158,6 +252,9 @@ namespace EveryThing.Pages.Projects
string value = row.Cell(excelItem.CellIndex).Value.ToString();
if (string.IsNullOrWhiteSpace(value))
continue;
if (excelItem.Name is "IdItemFk" or "IdMaterialFk")
{
var completableItem = _context.CodeTableItems.FirstOrDefault(x => x.Title == value && x.Active == true);
@@ -218,7 +315,7 @@ namespace EveryThing.Pages.Projects
System.IO.File.Delete(path);
return RedirectToPage("./Edit", new {id = IdProject});
return new JsonResult(new { successful = true, redirectUrl = Url.Page("./Edit", new { id = IdProject }) });
}
public class ExcelItem