Я создаю веб-приложение для обзора статьи.
У меня есть таблица с именем Article, и у каждого Article
есть несколько ArticleReview
:
Article
ArticleId
ArticleTitle
NumberOfComment
NumberOfView
...
ICollection<ArticleReview> Reviews
Администратор может добавить много пользователей (я называю их JueryUser) и отправить им статью для просмотра, я использую таблицу с именем ArticlePoint для добавления / удаления пользователей, которые могут просматривать каждую статью:
ArticlePoint
public int ArticlePointId { get; set; }
public DateTime CreateOn { get; set; }
public string Id { get; set; } // Id of User that review Article
public ApplicationUser JuryUser { get; set; }
public string UserId { get; set; } // Id of User that write Article
public int ArticleId { get; set; }
public string JuryReview { get; set; }
Когда рецензируемая статья присяжного пользователя он / она дал статье какой-то балл, этот балл основан на вопросах, заданных администратором, этот обзор хранится в таблице ArticleReview
.
ArticleReview
ArticleReviewId
ReviewPoint
ArticleId
ReviewerId
Как я уже говорил в мой предыдущий вопрос Я хочу получить экспорт Excel из суммы баллов, которую дали статьи каждому жюри.
Я использую этот код ниже для создания моего файла Excel:
public static class ExcelExportHelper
{
public static string ExcelContentType => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
public static DataTable ListToDataTable<T>(List<T> data)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable dataTable = new DataTable();
for (int i = 0; i < properties.Count; i++)
{
PropertyDescriptor property = properties[i];
dataTable.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
}
object[] values = new object[properties.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = properties[i].GetValue(item);
}
dataTable.Rows.Add(values);
}
return dataTable;
}
public static byte[] ExportExcel(DataTable dataTable, string heading = "", bool showSrNo = false, params string[] columnsToTake)
{
byte[] result = null;
using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet workSheet = package.Workbook.Worksheets.Add(String.Format("{0} Data", heading));
workSheet.View.RightToLeft = true;
int startRowFrom = String.IsNullOrEmpty(heading) ? 1 : 3;
if (showSrNo)
{
DataColumn dataColumn = dataTable.Columns.Add("#", typeof(int));
dataColumn.SetOrdinal(0);
int index = 1;
foreach (DataRow item in dataTable.Rows)
{
item[0] = index;
index++;
}
}
// add the content into the Excel file
workSheet.Cells["A" + startRowFrom].LoadFromDataTable(dataTable, true);
// format header - bold, yellow on black
using (ExcelRange r = workSheet.Cells[startRowFrom, 1, startRowFrom, dataTable.Columns.Count])
{
r.Style.Font.Color.SetColor(System.Drawing.Color.White);
r.Style.Font.Bold = true;
r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
r.Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#1fb5ad"));
}
// format cells - add borders
using (ExcelRange r = workSheet.Cells[startRowFrom + 1, 1, startRowFrom + dataTable.Rows.Count, dataTable.Columns.Count])
{
r.Style.Border.Top.Style = ExcelBorderStyle.Thin;
r.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
r.Style.Border.Left.Style = ExcelBorderStyle.Thin;
r.Style.Border.Right.Style = ExcelBorderStyle.Thin;
r.Style.Border.Top.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Left.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);
}
if (!String.IsNullOrEmpty(heading))
{
workSheet.Cells["A1"].Value = heading;
workSheet.Cells["A1"].Style.Font.Size = 20;
workSheet.InsertColumn(1, 1);
workSheet.InsertRow(1, 1);
workSheet.Column(1).Width = 5;
}
result = package.GetAsByteArray();
}
return result;
}
public static byte[] ExportExcel<T>(List<T> data, string Heading = "", bool showSlno = false, params string[] ColumnsToTake)
{
return ExportExcel(ListToDataTable<T>(data), Heading, showSlno, ColumnsToTake);
}
}
и использую этот код в своем методе действия:
public ActionResult ExportToExcel()
{
byte[] filecontent;
try
{
var juryLists = from user in db.Users
where user.Roles.Any(r => r.RoleId == "IdOfRole")
select user;
var articles = db.Articles.Include(r=>r.ArticleReview).Where(r2=>r2.ArticleReviews.Any()).ToList();
List<string> cmnList = new List<string>();
cmnList.Add("Article Title");
cmnList.Add("Point Avarage");
var juryListNames = juryLists.OrderBy(x=>x.Id).Select(x => "JuryPoints : " + x.FullName).ToList();
cmnList.AddRange(juryListNames);
string[] columns = cmnList.ToArray();
var heading = $"Results";
var dt = new DataTable();
foreach (var column in columns)
{
dt.Columns.Add(column, typeof(string));
}
foreach (var item in articles)
{
var _obj = new object[] { item.ArticleTitle, item.ArticleReviews.OrderBy(x=>x.JuryUserId).Select(x=>x.ArticlePoint).Average() }.Concat(
item.ArticleReviews.OrderBy(x => x.JuryUserId).GroupBy(x => x.JuryUserId).Select(x => x.Average(y => y.ReviewPoint))
.Cast<object>()).ToArray();
dt.Rows.Add(_obj);
}
filecontent = ExcelExportHelper.ExportExcel(dt, heading, true, columns);
}
catch (Exception e)
{
return RedirectToAction("Details",new {id= id });
}
return File(filecontent, ExcelExportHelper.ExcelContentType, "Results.xlsx");
}
Моя проблема:
Я создаю заголовок для моего Excel, но проблема в том, что какой-то пользователь жюри еще не дал оценку статье, а когда я создаю Excel, точка другого жюри помещается в столбец другой.
ex: одна статья отправлена 5 жюри 1,2и 5 указывают на статью, но после того, как точка экспорта 5-го жюри в столбце 3-го жюри, как я могу решить это?