2010-07-22 5 views
6

Je n'arrive pas à trouver celui-ci.C# Ouvrir Xml SDK 2.0 Tableur Configurer la cellule DateTime Format

ma situation:

  • SDK 2.0
  • pas tableur modèle
  • C# 4.0 dans VS2010

mon problème:
Certaines données contenues dans les fichiers Excel Je veux construire existe au format DateTime. Comme je ne veux pas utiliser uniquement des chaînes (les dattes à cordes ne peuvent pas être triées correctement), je veux définir les cellules contenant DateTime dans un format de mon choix comme je le ferais dans Excel. Pour ma compréhension, je dois utiliser une feuille de style pour arriver à ce point. J'ai navigué sur le web depuis un moment maintenant pour trouver quelqu'un qui a une explication simple à ce problème, mais il semble que c'est difficile à trouver.

J'ai déjà une feuille de calcul dans mem, avec la possibilité d'ajouter des données, à travers SheetData. la seule chose qui me manque est le formatage/style des cellules.

c'est de savoir jusqu'où je suis arrivé:

DocumentFormat.OpenXml.Packaging.SpreadsheetDocument doc = SpreadsheetDocument.Create("test.xlsx", SpreadsheetDocumentType.Workbook); 

WorkbookPart wbPart = doc.AddWorkbookPart(); 
wbPart.Workbook = new Workbook(); 

SheetData data = new SheetData(
      new Row(...etc)); 

WorksheetPart wsPart = wbPart.AddNewPart<WorksheetPart>(); 
wsPart.Worksheet = new Worksheet(data); 

Sheets sheets = doc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets()); 

Sheet sheet = new Sheet() { Id = doc.WorkbookPart.GetIdOfPart(wsPart), SheetId = 1, Name = "TestSheet" }; 
sheets.Append(sheet); 

wbPart.Workbook.Save(); 

doc.Close(); 

où et comment puis-je ajouter des additions simples au style comme le temps de la date (ex, « dd-MM-AAAA »), et le style peut-être plus avancé plus tard ?

J'espère avoir été assez précis :) en attendant, je vais continuer à regarder ...

!!! THX

+0

Avez-vous déjà travaillé cela? –

+0

N'avez-vous pas lu les spécifications Office Open XML? C'est seulement 6.000 pages ... :-) jk bien sûr, je me bats avec des "petits" problèmes similaires en ce moment. –

+1

non je n'ai jamais fait, désolé à ce sujet ... nous avons décidé d'utiliser un outil tiers qui rend les feuilles :) –

Répondre

3

La mise en forme de nombres en tant que dates est très complexe.

Vous devez commencer par le format numérique. Soit identifier le format intégré qui correspond au modèle que vous voulez ou en créer un personnalisé. Les formats intégrés sont ECMA-376, deuxième édition, Partie 1 - Notions de base et langage de balisagesection 18.8.30 (la référence pour les styles et <numFmt>) Si vous devez créer un format personnalisé, commencez par l'ID 164 et ajoutez-les . l'élément <numFmts> de votre fichier styles.xml Ceci est accessible dans le SDK comme:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats 

Ensuite, vous devez avoir un format de cellule qui fait référence à un format de date vous avez toujours besoin d'un format de cellule, il n'y a pas intégré. Le style de cellule fait référence au format de nombre par numFmtId et est défini à l'intérieur de styles.xml à l'intérieur de <cellXfs>. Ceci est accessible dans le sdk comme:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.CellStyles 

Les styles de cellule eux-mêmes n'ont pas d'ID. Ils sont référencés par la position d'index zéro dans la liste des styles de cellules. Ainsi, lorsque vous créez vos cellules, définissez leur index de style sur le style que vous souhaitez pour vos dates. Pour la valeur, vous pouvez les stocker au format ISO 8601 mais Excel 2010 utilise toujours le format série de date pour stocker ses dates. Si vous utilisez autre chose que la série de dates 1900, vous devez le spécifier dans les propriétés du classeur.

doc.WorkbookPart.Workbook.WorkbookProperties.DateCompatibility 

Il y a deux jour les paramètres de compatibilité pour le stockage des valeurs de date série, ils peuvent être la base 1900 ou la base 1904. 1900 est ce que Excel 2010 utilise et 1904 est pour la compatibilité descendante avec les anciens Excel pour Mac.

En 1900, les numéros de série sont les jours depuis le 31 décembre 1899 avec la complication supplémentaire que vous devez traiter le 29 février 1900 comme une date valide même si techniquement, 1900 n'est pas une année bissextile.

Ci-dessous est la méthode que j'ai écrite pour la conversion de valeurs de date en date à DateTime. Vous avez besoin de l'inverse.

/// <summary> 
/// Represents the formula used for converting date serial values stored within the workbook into DateTime instances. 
/// </summary> 
/// <remarks> 
/// Information on date serial conversion is available here: http://www.documentinteropinitiative.com/implnotes/ISO-IEC29500-2008/001.018.017.004.001.000.000.aspx 
/// </remarks> 
public enum XlsxDateCompatibility 
{ 
    /// <summary> 
    /// Standard dates are based on December 30, 1899 and are considered "Standard 1900" dates. 
    /// </summary> 
    StandardBase1900, 

    /// <summary> 
    /// Excel for Windows backwards compatible dates are based on December 31, 1899 are are considered "Backwards compatible 1900" dates. 
    /// </summary> 
    BackwardsCompatibleBase1900, 

    /// <summary> 
    /// Excel for Macintos backwards compatible dates are based on January 1, 1904 and are considered "1904" dates. 
    /// </summary> 
    BackwardsCompatibleBase1904 
} 

    private static readonly IDictionary<XlsxDateCompatibility, DateTime> _dateSerialBaseDates 
     = new Dictionary<XlsxDateCompatibility, DateTime> 
      { 
       {XlsxDateCompatibility.StandardBase1900, new DateTime(1899, 12, 30)}, 
       {XlsxDateCompatibility.BackwardsCompatibleBase1900, new DateTime(1899, 12, 31)}, 
       {XlsxDateCompatibility.BackwardsCompatibleBase1904, new DateTime(1904, 1, 1)} 
      }; 

    public static DateTime DateSerialToDateTime(double dateSerial, XlsxDateCompatibility dateCompatibility) 
    { 

     // special case for dateCompaitility 1900, Excel thinks 1900 is a leap year 
     // http://support.microsoft.com/kb/214019 
     if (dateCompatibility == XlsxDateCompatibility.BackwardsCompatibleBase1900 && dateSerial >= 61.0) 
     { 
      dateSerial -= 1; 
     } 

     DateTime baseDate;   
     if (!_dateSerialBaseDates.TryGetValue(dateCompatibility, out baseDate)) 
     { 
      baseDate = _dateSerialBaseDates[XlsxDateCompatibility.StandardBase1900]; 
     } 
     return baseDate.AddDays(dateSerial); 
    }