web-dev-qa-db-fra.com

Comment définir le type de colonne lors de l'utilisation de EPPlus

J'utilise EPPlus pour générer des fichiers Excel. Dans DAL, je renseigne DataTable, je complète les données dans une table et je passe la table à la couche de présentation. De là, j'utilise la méthode LoadFromDataTable() pour générer le fichier Excel

Tout fonctionne bien, sauf que je souhaite définir l'un des types de colonne sur Date. J'ai essayé de définir le type de colonne de mon DataTable sur Date et de passer DataTable à Presentation Layer, mais il semble que EPPlus soit l'a ignoré ou ne soit pas reconnu, car lorsque j'ouvre un fichier Excel généré, le type de cellule est Number

Si je mets manuellement en forme les cellules et que le type est défini sur Date, Excel affiche les dates correctes. Alors, comment puis-je y parvenir?

56
Michael

La colonne DataTable doit avoir le bon type, mais vous devez également modifier la propriété Style.Numberformat.Format de la colonne ou de la cellule.

Disons que vous avez une ExcelWorksheet nommée ws:

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

Sur la base de cette discussion ( epplus.codeplex.com/discussions/349927 ), vous pouvez également définir le format de colonne à date.

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

37
insilenzio

Si vos colonnes sont susceptibles de se déplacer (comme nous le savons les utilisateurs finaux ont tendance à être instables) ou si vous avez simplement plusieurs colonnes de date dispersées sur votre feuille de calcul, il serait utile d'écrire quelque chose d'un peu plus générique. Voici ce que je viens d'écrire. Il trouve la position de tous les types DateTime dans mon POCO et crée une liste qu'il utilise ensuite pour définir le formatage des colonnes. Rappelez-vous que les tableaux de données sont basés sur zéro et Excel non.

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

Si vous faites plus d'une datatable, vous voudrez probablement le refactoriser dans une fonction.

Et voici un billet de faveur ... Je ne peux pas prendre crédit pour ce code. Il faut une liste POCO et la transforme en table de données. Cela m’a simplifié la vie à plusieurs reprises en l’ayant dans ma «boîte à outils». Prendre plaisir.

        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;
    }
2
midohioboarder

Pour utiliser les formats Excel intégrés, vous devez transmettre la chaîne correcte à

sheet.Cells[1, 1].Style.Numberformat.Format 

propriété.

Maintenant, quelque part plus tard au cours de l'exécution, probablement lors de la sérialisation, EPPlus tentera de faire correspondre cette propriété de format au dictionnaire de styles actuel du classeur. Cela peut dépendre de la version exacte de la bibliothèque, mais par exemple, pour EPPlust 4.1.0.0, la clé de date courte est "mm-jj-aa".

Pour 4.1.0.0, vous pouvez trouver tous les codes et clés codés en dur pour créer des formats dans:

  1. ExcelNumberFormatXml.cs, internal static void AddBuildIn(XmlNamespaceManager NameSpaceManager, ExcelStyleCollection<ExcelNumberFormatXml> NumberFormats) - ici, tous ces codes sont réellement inclus dans le classeur, tous codés en dur
  2. utiliser le débogueur et vérifier l'énumération Workbook.Styles.NumberFormats (en tant que clé, utiliser ExcelNumberFormatXml.Format
  3. utilisez le débogueur et vérifiez Workbook.Styles.NumberFormats. (membre non public) _dic pour les clés exactes.
1
Michał Brix

Voici une méthode d'extension Nice C # pour vous aider à charger de la collection avec des en-têtes et le formatage de date approprié:

(Décorez vos propriétés avec les attributs Description pour les en-têtes de colonne)

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";
            }
        }
    } 
}
0
Brennan Pope