0

场景是生成一个包含约 150 个数据列的 excel 报告。现在我需要管理列属性,如宽度、背景颜色、字体等。

我使用的方法依赖于反射。我有一个类,它有大约 150 个列标题文本常量。另一个用于存储列属性的自定义属性类。这些属性应用于常量。

在使用反射创建列期间,我正在访问所有常量以创建标题文本(类中的常量排序定义列排序)和列属性的属性。

private void CreateHeader(Excel.Worksheet xl_WorkSheet, FieldInfo[] fi_Header)
    {
        ColumnProperties c;
        System.Attribute[] customAttributes;
        for (int i = 0; i < fi_Header.GetLength(0); i++)
        {
            xl_WorkSheet.get_Range(xl_WorkSheet.Cells[1, i+1], xl_WorkSheet.Cells[2, i+1]).Merge(false);

            //Set the header text.
            xl_WorkSheet.get_Range(xl_WorkSheet.Cells[1, i + 1], xl_WorkSheet.Cells[2, i + 1]).FormulaR1C1 = 
                fi_Header[i].GetValue(null).ToString();
            //Set cell border.
            xl_WorkSheet.get_Range(xl_WorkSheet.Cells[1, i + 1],
                xl_WorkSheet.Cells[2, i + 1]).BorderAround(Excel.XlLineStyle.xlContinuous,
                Excel.XlBorderWeight.xlThin, Excel.XlColorIndex.xlColorIndexAutomatic, Missing.Value);

            //Get custom attribute ~ Column attribute.
            customAttributes = (System.Attribute[])fi_Header[i].GetCustomAttributes(typeof(ColumnProperties), false);
            if (customAttributes.Length > 0)
            {
                c = (ColumnProperties)customAttributes[0];
                //Set column properties.
                xl_WorkSheet.get_Range(xl_WorkSheet.Cells[1, i + 1],
                    xl_WorkSheet.Cells[2, i + 1]).Interior.Color =
                    System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.FromName(c.Color));

                xl_WorkSheet.get_Range(xl_WorkSheet.Cells[1, i + 1],
                    xl_WorkSheet.Cells[2, i + 1]).ColumnWidth = c.Width;
            }                
        }
    }

编辑:获取常量的代码

private FieldInfo[] GetHeaderConstants(System.Type type)
    {
        ArrayList constants = new ArrayList();
        FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
        foreach (FieldInfo fi in fieldInfos)
        {
            if (fi.IsLiteral && !fi.IsInitOnly)
                constants.Add(fi);
        }
        return (FieldInfo[])constants.ToArray(typeof(FieldInfo));
    }   

主要目标是使 excel 文件生成通用/不易维护。该方法是否可行,或者还有其他更好的选择。

编辑 2:常量类

public class ExcelHeaders
{
    [ColumnProperties(Width=10, Color="LemonChiffon")]
    public const string S_NO = "S.No";

    [ColumnProperties(Width = 20, Color = "WhiteSmoke")]
    public const string COLUMN_HEADER = "Header Text";
}
4

2 回答 2

1
  1. 反思的需要在哪里发挥作用?
  2. 我认为您不能依靠反射来按照您在源代码中声明它们的顺序返回常量。

编辑:

好吧,我一定遗漏了一些东西——我真的不明白你在思考什么,如果不是你自己创造的东西,而且你可以很容易地获得参考。

似乎您可以像这样创建一个类:

public class ColumnProperties
{
   readonly string m_HeaderText;
   public ColumnProperties(string headerText, Color color, int width) { ... }
   public string HeaderText { get { return m_HeaderText; }
   public Color FontColor { get; set; }
   public int Width { get; set; }
   ...
}

然后,如果您有 150 个数据点,则创建 150 个ColumnProperties对象。将这些集合传递到您的CreateHeader()方法中,并忘记所有无端的反射和那些自定义属性。

于 2010-01-28T07:07:46.233 回答
1

您的方法的一个特点是,如果要更改列的外观,则需要更改源。我更喜欢将外观数据存储在某种 XML 配置中。如果可用,您可以从外部配置文件加载配置,或者从嵌入在可执行文件中作为资源的默认配置加载配置。这使您可以灵活地在运行时更改配置,只需添加配置文件即可。

您的 XML 文档可能如下所示:

  <Appearance>
    <!-- Defaults to use for attributes not explicitly specified -->
    <Defaults HeaderText="" Width="10" Color="White" />
    <Columns>
      <Column HeaderText="S.No" Width="10" Color="LemonChiffon" />
      <Column HeaderText="Header Text" Width="20" Color="WhiteSmoke" />
    </Columns>
  </Appearance>
于 2010-01-28T07:51:05.840 回答