代码之家  ›  专栏  ›  技术社区  ›  A G

C#Excel-管理列属性

  •  0
  • A G  · 技术社区  · 15 年前

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

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

    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));
        }   
    

    编辑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";
    }
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   to StackOverflow    15 年前

    这种方法的一个特点是,如果要更改列的外观,则需要更改源代码。我更喜欢将外观数据存储在某种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>
    
        2
  •  1
  •   Community CDub    4 年前
    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() 方法,并忘记所有那些毫无意义的反射和那些自定义属性。