【问题标题】:Gathering Data For ClosedXML Using foreach Loop使用 foreach 循环为 ClosedXML 收集数据
【发布时间】:2017-07-18 12:03:45
【问题描述】:

我的 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");
    }
}

【问题讨论】:

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


    【解决方案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");
            }
    

    【讨论】:

    • 这行得通。基本上,我没有使用正确类型的循环?
    • 这不是循环的类型(有一个使用 foreach 循环的解决方案),更多的是不将工单项目添加到工作表并更新循环内的单元格引用.
    • 哦,好的。我懂了。循环无法将数据添加到其余单元格,因为我没有告诉它。
    • @Michael 当场!我还更新了我的答案以显示使用 foreach 的解决方案。任何一种都可以,尽管有些人会对首选方法有强烈的看法!
    【解决方案2】:

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

    【讨论】:

    • 我试过了,但我的 excel 表格中仍然有一张票。
    • 每次循环时,单元格标识符都需要更新。 @Ankush Jain 的回答显示了一种方法。如果您对他的答案对您感到满意,则应将其标记为已接受的答案。
    • 很棒的补充。非常感谢!
    【解决方案3】:

    与其使用自己的循环,更好的方法是使用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

    【讨论】:

      猜你喜欢
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      • 2015-12-26
      • 2012-04-10
      • 1970-01-01
      • 2013-12-22
      • 2012-04-10
      相关资源
      最近更新 更多