首页 > 解决方案 > 与Epplus一起使用时如何对类的属性进行序列化时对列进行排序

问题描述

我正在使用 Epplus 库将集合中的数据导出到 excel 文件。我希望输出按类中指定的属性顺序排列。我确实发现有 DataMember,但它仅用于 WCF。我正在使用 WPF 开发应用程序

标签: c#serializationepplus

解决方案


您是否要求根据列中的属性对行进行排序?或者您是否真的想在输出列时对其进行排序。在任何一种情况下,都没有可以使用 Epplus 本身支持 AFAIK 的属性。

如果您想按列对行进行排序,请查看Sort他们几年前添加的功能:

https://github.com/JanKallman/EPPlus/blob/4dacf27661b24d92e8ba3d03d51dd5468845e6c1/EPPlus/ExcelRangeBase.cs#L2934

但是,根据您的描述,您希望在导出things具有类似LoadFromCollection. 您可以轻松地创建自己的属性,然后使用采用以下集合的重载MemberInfo

public class ExportOrderAttribute : Attribute
{
    public ExportOrderAttribute(int order)
    {
        Order = order;
    }

    public int Order { get; set; }
}

public class TestObject
{
    /// <summary>
    /// Best to make static to avoid repeat calls to Reflections (if possible).
    /// </summary>
    public static MemberInfo[] MemberSortInfo { get; } = typeof(TestObject)
        .GetProperties()
        .Select(pi => new
        {
            Property = pi,
            Attribute = (ExportOrderAttribute) Attribute.GetCustomAttribute(
                pi
                , typeof(ExportOrderAttribute)
                , true
            )
        })
        .OrderBy(a => a.Attribute?.Order ?? -1)
        .Select(a => a.Property)
        .Cast<MemberInfo>()
        .ToArray();

    [ExportOrder(4)]
    public int IntCol1 { get; set; }

    [ExportOrder(3)]
    public int IntCol2 { get; set; }

    [ExportOrder(2)]
    public string StringCol { get; set; }

    [ExportOrder(1)]
    public DateTime DateCol { get; set; }

    [ExportOrder(0)]
    public int IntCol3 { get; set; }
}

[TestMethod]
public void Sort_Column_Output()
{
    //https://stackoverflow.com/questions/58177582/how-to-sort-columns-when-serializing-the-properties-of-a-class-when-used-with-ep

    var rnd = new Random();

    var testObjects = Enumerable
        .Range(0, 10)
        .Select(i => new TestObject
        {
            IntCol1 = i,
            IntCol2 = i * 10,
            StringCol = Path.GetRandomFileName(),
            DateCol = DateTime.Now.AddDays(rnd.Next(0, 100)),
            IntCol3 = rnd.Next(100, 10000)
        })
        .ToList();

    var fi = new FileInfo("c:\\temp\\Sort_Column_Output.xlsx");
    if (fi.Exists)
        fi.Delete();

    using (var pck = new ExcelPackage(fi))
    {
        var worksheet = pck.Workbook.Worksheets.Add("Sheet1");

        worksheet.Cells.LoadFromCollection(
            testObjects
            , true
            , TableStyles.None
            , BindingFlags.Instance | BindingFlags.Public
            , TestObject.MemberSortInfo  //CONTROLS THE SORTING
        );

        pck.Save();
    }
}

这给出了这个:

在此处输入图像描述


推荐阅读