使用 foreach 循环为 ClosedXML 收集数据
Gathering Data For ClosedXML Using foreach Loop
我的 C# ASP.NET MVC5 应用程序有一个名为 Ticket 的模型。我想使用 ClosedXML 将数据库中的所有门票导出到 excel 电子表格。我有一个仅用于将数据导出和下载到电子表格的操作。一切都很好,除了当我打开我新下载的电子表格时,我只有一张票。我认为我的 foreach 循环没有恰到好处的东西。我做错了什么?
当用户想要下载门票时调用的我的操作:
public ActionResult DownloadTickets()
{
string date = "";
string title = "";
string createdBy = "";
bool isCallBack = true;
using (var wb = new XLWorkbook())
{
var ticket = _context.Tickets.ToList();
var dateForXcellSheet = DateTime.Now;
var worksheet = wb.Worksheets.Add("Sample Sheet");
foreach (var i in ticket)
{
date = i.DateCreated.ToString();
title = i.Title;
createdBy = i.CreatedBy;
isCallBack = i.IsCallBack;
}
worksheet.Cell("A1").Value = date;
worksheet.Cell("B1").Value = title;
worksheet.Cell("C1").Value = createdBy;
worksheet.Cell("D1").Value = isCallBack;
// Add ClosedXML.Extensions in your using declarations
return wb.Deliver("tickets-" + dateForXcellSheet + ".xlsx");
}
}
将数据添加到工作表单元格(以及可能添加 ClosedXML 扩展)的代码也需要在 foreach
循环内。就目前而言,您正在遍历所有票证,但只有最后一张票证的 属性 值被添加到电子表格中。
编辑: 正如 OP 在对已接受答案的评论中所问... ...使用 foreach
可以获得相同的结果循环:
var rowIndex = 1;
foreach (var ticket in ticketList)
{
date = ticket.DateCreated.ToString();
title = ticket.Title;
createdBy = ticket.CreatedBy;
isCallBack = ticket.IsCallBack;
worksheet.Cell("A" + rowIndex).Value = date;
worksheet.Cell("B" + rowIndex).Value = title;
worksheet.Cell("C" + rowIndex).Value = createdBy;
worksheet.Cell("D" + rowIndex).Value = isCallBack;
rowIndex++;
}
像下面这样更改您的代码。使用 for 循环并使用适当的索引为电子表格中的单元格赋值。
using (var wb = new XLWorkbook())
{
var ticketList = _context.Tickets.ToList();
var dateForXcellSheet = DateTime.Now;
var worksheet = wb.Worksheets.Add("Sample Sheet");
for (int i= 0; i < ticketList.Count(); i++)
{
date = ticketList[i].DateCreated.ToString();
title = ticketList[i].Title;
createdBy = ticketList[i].CreatedBy;
isCallBack = ticketList[i].IsCallBack;
int index = i + 1;
worksheet.Cell("A" + index).Value = date;
worksheet.Cell("B" + index).Value = title;
worksheet.Cell("C" + index).Value = createdBy;
worksheet.Cell("D" + index).Value = isCallBack;
}
// Add ClosedXML.Extensions in your using declarations
return wb.Deliver("tickets-" + dateForXcellSheet + ".xlsx");
}
与其使用自己的循环,更好的方法是使用 IXLCell.InsertData(data)
示例:
public void Create()
{
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("Inserting Data");
// From a list of strings
var listOfStrings = new List<String>();
listOfStrings.Add("House");
listOfStrings.Add("Car");
ws.Cell(1, 1).Value = "From Strings";
ws.Cell(1, 1).AsRange().AddToNamed("Titles");
var rangeWithStrings = ws.Cell(2, 1).InsertData(listOfStrings);
// From a list of arrays
var listOfArr = new List<Int32[]>();
listOfArr.Add(new Int32[] { 1, 2, 3 });
listOfArr.Add(new Int32[] { 1 });
listOfArr.Add(new Int32[] { 1, 2, 3, 4, 5, 6 });
ws.Cell(1, 3).Value = "From Arrays";
ws.Range(1, 3, 1, 8).Merge().AddToNamed("Titles");
var rangeWithArrays = ws.Cell(2, 3).InsertData(listOfArr);
// From a DataTable
var dataTable = GetTable();
ws.Cell(6, 1).Value = "From DataTable";
ws.Range(6, 1, 6, 4).Merge().AddToNamed("Titles");
var rangeWithData = ws.Cell(7, 1).InsertData(dataTable.AsEnumerable());
// From a query
var list = new List<Person>();
list.Add(new Person() { Name = "John", Age = 30, House = "On Elm St." });
list.Add(new Person() { Name = "Mary", Age = 15, House = "On Main St." });
list.Add(new Person() { Name = "Luis", Age = 21, House = "On 23rd St." });
list.Add(new Person() { Name = "Henry", Age = 45, House = "On 5th Ave." });
var people = from p in list
where p.Age >= 21
select new { p.Name, p.House, p.Age };
ws.Cell(6, 6).Value = "From Query";
ws.Range(6, 6, 6, 8).Merge().AddToNamed("Titles");
var rangeWithPeople = ws.Cell(7, 6).InsertData(people.AsEnumerable());
// Prepare the style for the titles
var titlesStyle = wb.Style;
titlesStyle.Font.Bold = true;
titlesStyle.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
titlesStyle.Fill.BackgroundColor = XLColor.Cyan;
// Format all titles in one shot
wb.NamedRanges.NamedRange("Titles").Ranges.Style = titlesStyle;
ws.Columns().AdjustToContents();
wb.SaveAs("InsertingData.xlsx");
}
class Person
{
public String House { get; set; }
public String Name { get; set; }
public Int32 Age { get; set; }
}
private DataTable GetTable()
{
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(25, "Indocin", "David", DateTime.Now);
table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
return table;
}
参考https://github.com/ClosedXML/ClosedXML/wiki/Inserting-Data
我的 C# ASP.NET MVC5 应用程序有一个名为 Ticket 的模型。我想使用 ClosedXML 将数据库中的所有门票导出到 excel 电子表格。我有一个仅用于将数据导出和下载到电子表格的操作。一切都很好,除了当我打开我新下载的电子表格时,我只有一张票。我认为我的 foreach 循环没有恰到好处的东西。我做错了什么?
当用户想要下载门票时调用的我的操作:
public ActionResult DownloadTickets()
{
string date = "";
string title = "";
string createdBy = "";
bool isCallBack = true;
using (var wb = new XLWorkbook())
{
var ticket = _context.Tickets.ToList();
var dateForXcellSheet = DateTime.Now;
var worksheet = wb.Worksheets.Add("Sample Sheet");
foreach (var i in ticket)
{
date = i.DateCreated.ToString();
title = i.Title;
createdBy = i.CreatedBy;
isCallBack = i.IsCallBack;
}
worksheet.Cell("A1").Value = date;
worksheet.Cell("B1").Value = title;
worksheet.Cell("C1").Value = createdBy;
worksheet.Cell("D1").Value = isCallBack;
// Add ClosedXML.Extensions in your using declarations
return wb.Deliver("tickets-" + dateForXcellSheet + ".xlsx");
}
}
将数据添加到工作表单元格(以及可能添加 ClosedXML 扩展)的代码也需要在 foreach
循环内。就目前而言,您正在遍历所有票证,但只有最后一张票证的 属性 值被添加到电子表格中。
编辑: 正如 OP 在对已接受答案的评论中所问... ...使用 foreach
可以获得相同的结果循环:
var rowIndex = 1;
foreach (var ticket in ticketList)
{
date = ticket.DateCreated.ToString();
title = ticket.Title;
createdBy = ticket.CreatedBy;
isCallBack = ticket.IsCallBack;
worksheet.Cell("A" + rowIndex).Value = date;
worksheet.Cell("B" + rowIndex).Value = title;
worksheet.Cell("C" + rowIndex).Value = createdBy;
worksheet.Cell("D" + rowIndex).Value = isCallBack;
rowIndex++;
}
像下面这样更改您的代码。使用 for 循环并使用适当的索引为电子表格中的单元格赋值。
using (var wb = new XLWorkbook())
{
var ticketList = _context.Tickets.ToList();
var dateForXcellSheet = DateTime.Now;
var worksheet = wb.Worksheets.Add("Sample Sheet");
for (int i= 0; i < ticketList.Count(); i++)
{
date = ticketList[i].DateCreated.ToString();
title = ticketList[i].Title;
createdBy = ticketList[i].CreatedBy;
isCallBack = ticketList[i].IsCallBack;
int index = i + 1;
worksheet.Cell("A" + index).Value = date;
worksheet.Cell("B" + index).Value = title;
worksheet.Cell("C" + index).Value = createdBy;
worksheet.Cell("D" + index).Value = isCallBack;
}
// Add ClosedXML.Extensions in your using declarations
return wb.Deliver("tickets-" + dateForXcellSheet + ".xlsx");
}
与其使用自己的循环,更好的方法是使用 IXLCell.InsertData(data)
示例:
public void Create()
{
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("Inserting Data");
// From a list of strings
var listOfStrings = new List<String>();
listOfStrings.Add("House");
listOfStrings.Add("Car");
ws.Cell(1, 1).Value = "From Strings";
ws.Cell(1, 1).AsRange().AddToNamed("Titles");
var rangeWithStrings = ws.Cell(2, 1).InsertData(listOfStrings);
// From a list of arrays
var listOfArr = new List<Int32[]>();
listOfArr.Add(new Int32[] { 1, 2, 3 });
listOfArr.Add(new Int32[] { 1 });
listOfArr.Add(new Int32[] { 1, 2, 3, 4, 5, 6 });
ws.Cell(1, 3).Value = "From Arrays";
ws.Range(1, 3, 1, 8).Merge().AddToNamed("Titles");
var rangeWithArrays = ws.Cell(2, 3).InsertData(listOfArr);
// From a DataTable
var dataTable = GetTable();
ws.Cell(6, 1).Value = "From DataTable";
ws.Range(6, 1, 6, 4).Merge().AddToNamed("Titles");
var rangeWithData = ws.Cell(7, 1).InsertData(dataTable.AsEnumerable());
// From a query
var list = new List<Person>();
list.Add(new Person() { Name = "John", Age = 30, House = "On Elm St." });
list.Add(new Person() { Name = "Mary", Age = 15, House = "On Main St." });
list.Add(new Person() { Name = "Luis", Age = 21, House = "On 23rd St." });
list.Add(new Person() { Name = "Henry", Age = 45, House = "On 5th Ave." });
var people = from p in list
where p.Age >= 21
select new { p.Name, p.House, p.Age };
ws.Cell(6, 6).Value = "From Query";
ws.Range(6, 6, 6, 8).Merge().AddToNamed("Titles");
var rangeWithPeople = ws.Cell(7, 6).InsertData(people.AsEnumerable());
// Prepare the style for the titles
var titlesStyle = wb.Style;
titlesStyle.Font.Bold = true;
titlesStyle.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
titlesStyle.Fill.BackgroundColor = XLColor.Cyan;
// Format all titles in one shot
wb.NamedRanges.NamedRange("Titles").Ranges.Style = titlesStyle;
ws.Columns().AdjustToContents();
wb.SaveAs("InsertingData.xlsx");
}
class Person
{
public String House { get; set; }
public String Name { get; set; }
public Int32 Age { get; set; }
}
private DataTable GetTable()
{
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(25, "Indocin", "David", DateTime.Now);
table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
return table;
}
参考https://github.com/ClosedXML/ClosedXML/wiki/Inserting-Data