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?
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!
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;
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;
}
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:
internal static void AddBuildIn(XmlNamespaceManager NameSpaceManager, ExcelStyleCollection<ExcelNumberFormatXml> NumberFormats)
- ici, tous ces codes sont réellement inclus dans le classeur, tous codés en durWorkbook.Styles.NumberFormats
(en tant que clé, utiliser ExcelNumberFormatXml.Format
) Workbook.Styles.NumberFormats.
(membre non public) _dic
pour les clés exactes.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";
}
}
}
}