0

シナリオは、約150のデータ列を持つExcelレポートを生成することです。次に、Width、BackgroundColor、Fontなどの列のプロパティを管理する必要があります。

私が使用しているアプローチは、リフレクションに依存しています。列ヘッダーテキスト用に約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

あなたのアプローチの特徴の 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 に答える