web-dev-qa-db-ja.com

EPPlusを使用するときに列タイプを設定する方法

EPPlusを使用してExcelファイルを生成し、DALでDataTableを入力し、データをテーブルに入力し、プレゼンテーション層にテーブルを渡します。そこからLoadFromDataTable()メソッドを使用してExcelファイルを生成しています。

列のタイプの1つをDateに設定することを除いて、すべて正常に機能します。 DataTable to Dateの列タイプを設定して、DataTableをプレゼンテーション層に渡すことを試みましたが、EPPlusのいずれか、無視する、またはしなかったようです生成されたExcelファイルを開いているとき、セルのタイプはNumberであるため、認識できません。

セルを手動でフォーマットし、タイプをDateに設定すると、Excelは正しい日付を表示します。それでは、どうすればこれを達成できますか?

61
Michael

DataTable列には正しい型が必要ですが、列またはセルのStyle.Numberformat.Formatプロパティを変更する必要もあります。

ExcelWorksheetという名前のwsがあるとします:

ws.Column(1).Style.Numberformat.Format  = "yyyy-mm-dd"; 
//OR "yyyy-mm-dd h:mm" if you want to include the time!
80
banging

この説明に基づいて( epplus.codeplex.com/discussions/349927 )、列フォーマットを日付に設定することもできます。

worksheet_1.Cells[row, 3].Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.ShortDatePattern;

39
insilenzio

エンドユーザーが気まぐれになる傾向があることがわかっているため、列が移動する可能性がある場合や、スプレッドシート全体に日付列が散らばっている場合は、もう少し一般的なものを書くと便利です。これが私が書いたものです。 POCO内のすべてのDateTimeタイプの位置を見つけ、リストを作成して、列の書式設定に使用します。データテーブルはゼロベースであり、Excelはそうではないことに注意してください。

        ws.Cells.LoadFromDataTable(tbl, true);
        var dPos = new List<int>();
        for (var i = 0; i < tbl.Columns.Count; i++)
            if (tbl.Columns[i].DataType.Name.Equals("DateTime"))
                dPos.Add(i);
        foreach (var pos in dPos)
        {
            ws.Column(pos+1).Style.Numberformat.Format = "mm/dd/yyyy hh:mm:ss AM/PM";
        }

複数のデータテーブルを実行している場合は、おそらくリファクタリングして関数にしたいでしょう。

そして、ここに景品があります...私はこのコードを信用できません。 POCOリストを取得し、データテーブルに変換します。それは私の「ツールキット」でそれを持っている多くの機会に私の人生を楽にしました。楽しい。

        public DataTable ConvertToDataTable<T>(IList<T> data)
    {
        var properties =
           TypeDescriptor.GetProperties(typeof(T));
        var table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            var row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;
    }
5
midohioboarder

ヘッダーと適切な日付形式を使用してコレクションからロードするのに役立つ素敵なC#拡張メソッドを次に示します。

(列見出しの説明属性でプロパティを飾ります)

public static class EpPlusExtensions
{
    public static void Load<T>(this ExcelWorksheet worksheet, IEnumerable<T> collection)
    {
        worksheet.Cells["A1"].LoadFromCollection(collection, true);

        var properties = typeof(T).GetProperties();

        for (var i = 0; i < properties.Length; i++)
        {
            if (new []{typeof(DateTime), typeof(DateTime?)}.Contains(properties[i].PropertyType)) 
            {
                worksheet.Column(i + 1).Style.Numberformat.Format = "m/d/yyyy";
            }
        }
    } 
}
1
Brennan Pope

Excel形式でビルドを使用するには、正しい文字列を渡す必要があります

_sheet.Cells[1, 1].Style.Numberformat.Format 
_

プロパティ。

現在、実行中のどこか、おそらくシリアル化中に、EPPlusはこのフォーマットプロパティをワークブックのスタイルの現在の辞書と一致させようとします。正確なライブラリバージョンに依存しますが、たとえばEPPlust 4.1.0.0の短い日付キーは「mm-dd-yy」です。

4.1.0.0の場合、すべてのハードコードされたコードとキーを見つけて、次の形式でビルドできます。

  1. ExcelNumberFormatXml.cs、internal static void AddBuildIn(XmlNamespaceManager NameSpaceManager, ExcelStyleCollection<ExcelNumberFormatXml> NumberFormats)-これらのコードはすべて実際にワークブックに含まれ、すべてハードコードされています
  2. デバッガーを使用し、_Workbook.Styles.NumberFormats_列挙を確認します(キーとして_ExcelNumberFormatXml.Format_を使用します)
  3. デバッガを使用し、_Workbook.Styles.NumberFormats._(non public memeber)__dic_で正確なキーを確認してください。
1
Michał Brix