使用foreach循环为ClosedXML收集数据

时间:2017-07-18 12:03:46

标签: c# asp.net asp.net-mvc closedxml

我的C#ASP.NET MVC5应用程序有一个名为Ticket的模型。我想使用ClosedXML将数据库中的所有故障单导出到Excel电子表格中。我有一个Action用于导出和下载数据到电子表格。一切都很好,除非我打开新下载的电子表格,我只有一张票。我想我的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");
    }
}

3 个答案:

答案 0 :(得分:1)

将数据添加到工作表单元格(也可能是添加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++;
}

答案 1 :(得分:1)

更改您的代码,如下所示。使用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");
        }

答案 2 :(得分:1)

更好的方法是使用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