IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dotnet Discussion :

Créer un fichier xlsx bien formé avec open xml 2.0


Sujet :

Dotnet

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Créer un fichier xlsx bien formé avec open xml 2.0
    Bonjour,

    Je souhaiterai, via Open Xml 2.0 (.net 3.5 imposé), pouvoir créer un fichier xlsx n'ayant pas d'erreur à son ouverture.

    Après diverses recherches sur le web, j'en suis arrivé à faire cette classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    public class ExcelFileManager : FileManager
    {
        private SpreadsheetDocument _package;
     
        private Row _currentRow;
        private SheetData _sheetData;
     
        private int? _cellColumnN2;
        private int _cellColumnN1;
        private int _cellRow;
     
        public ExcelFileManager(string path) 
            : base(path)
        {
            _package = SpreadsheetDocument.Create(path, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
     
            _cellColumnN1 = 65;
            _cellRow = 1;
     
            CreateSpreadSheet();
        }
     
        private void CreateSpreadSheet()
        {
            var workbookPart1 = _package.AddWorkbookPart();
     
            workbookPart1.Workbook = new Workbook();
            var worksheetPart1 = workbookPart1.AddNewPart<WorksheetPart>();
            worksheetPart1.Worksheet = new Worksheet();
     
            var sheets = _package.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
            var sheet = new Sheet()
            {
                Id = _package.WorkbookPart.
                    GetIdOfPart(worksheetPart1),
                SheetId = 1,
                Name = "Users"
            };
            sheets.Append(sheet);
     
            _sheetData = new SheetData();
            _currentRow = new Row();
     
            _sheetData.Append(_currentRow);
            worksheetPart1.Worksheet.Append(_sheetData);
        }
     
        public override void AddHeader(IEnumerable<string> columnsName)
        {
            if (columnsName == null || !columnsName.Any())
                throw new ArgumentNullException("columnsName");
     
            try
            {
                AddRow(columnsName.ToArray());
            }
            catch (Exception e)
            {
                Tracing.Application.TraceError(-1, "An error occured when adding header to excel file", e);
     
                throw;
            }
        }
     
        public override void AddRow(params object[] values)
        {
            if (values == null || !values.Any())
                throw new ArgumentNullException("values");
     
            try
            {
                var listCells = new List<OpenXmlElement>();
     
                foreach (var item in values)
                {
                    listCells.Add(CreateCellRow(item));
                }
     
                _currentRow.Append(listCells);
     
                AddNewRow();
            }
            catch (Exception e)
            {
                Tracing.Application.TraceError(-1, "An error occured when adding row to excel file", e);
     
                throw;
            }
        }
     
        public override void AddCell(object value)
        {
            try
            {
                var cell = CreateCellRow(value);
     
                _currentRow.Append(cell);
            }
            catch (Exception e)
            {
                Tracing.Application.TraceError(-1, "An error occured when adding cell to excel file", e);
     
                throw;
            }
        }
     
        public override void AddNewRow()
        {
            _currentRow = new Row();
     
            _sheetData.Append(_currentRow);
     
            IncreaseRow();
        }
     
        #region Utils
        private Cell CreateCellRow(object value)
        {
            Tracing.Application.TraceInformation("Add value \"{0}\" in cell {1}", value, GetCellLocation());
     
            Cell cell = new Cell();
     
            if (value == null)
            {
                cell.CellValue = new CellValue(string.Empty);
                cell.DataType = CellValues.String;
            }
            else
            {                
                cell.CellValue = new CellValue(value.ToString());
                cell.DataType = GetCellType(value); 
            }
     
            cell.CellReference = GetCellLocation();
     
            IncreaseCellColumn();
     
            return cell;
        }
     
        private CellValues GetCellType(object value)
        {
            CellValues type = CellValues.String;
     
            if (value.GetType() == typeof(DateTime) || value.GetType() == typeof(DateTime?))
                type = CellValues.Date;
     
            if (value.GetType() == typeof(bool) || value.GetType() == typeof(bool?))
                type = CellValues.Boolean;
     
            if (IsNumericType(value.GetType()))
                type = CellValues.Number;
     
            return type;
        }
     
        public bool IsNumericType(Type type)
        {
            TypeCode typeCode = Type.GetTypeCode(type);
     
            //The TypeCode of numerical types are between SByte (5) and Decimal (15).
            return (int)typeCode >= 5 && (int)typeCode <= 15;
        }
     
        private void IncreaseCellColumn()
        {
            if (_cellColumnN1 < 90)
                _cellColumnN1++;
            else
            {
                _cellColumnN1 = 65;
     
                if (!_cellColumnN2.HasValue)
                    _cellColumnN2 = 65;
                else
                    _cellColumnN2++;
            }
        }
     
        private void IncreaseRow()
        {
            _cellRow++;
            _cellColumnN1 = 65;
            _cellColumnN2 = null;
        }
     
        private string GetCellLocation()
        {
            Char? c1 = null;
     
            if (_cellColumnN2.HasValue)
                c1 = (char)_cellColumnN2;
     
            Char c2 = (char)_cellColumnN1;
     
            return string.Format("{0}{1}{2}", c1, c2, _cellRow);
        }
        #endregion
     
        #region IDisposable
        public override void Dispose()
        {
            if (_package != null)
            {
                _package.WorkbookPart.Workbook.Save();
                _package.Close();
            }
        }
        #endregion
    }
    Lorsque j'ouvre le fichier xlsx créé en utilisant cette classe, une erreur du type "Désolé... Nous avons trouvé un problème dans le contenu de....".
    En demandant la récupération, ce message s'affiche : "Enregistrements réparés: Information de cellule dans la partie /xl/worksheets/sheet.xml".

    J'ai comparé les fichiers xml sheet.xml :

    Fichier généré :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
      <x:sheetData>
        <x:row>
          <x:c r="A1" t="str">
            <x:v>a string</x:v>
          </x:c>
          <x:c r="B1" t="str">
            <x:v>another string</x:v>
          </x:c>
        </x:row>
        ...
      </x:sheetData>
    </x:worksheet>
    Fichier réparé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
      <dimension ref="A1:S12"/>
      <sheetViews>
        <sheetView tabSelected="1" workbookViewId="0">
          <selection activeCell="I11" sqref="I11"/>
        </sheetView>
      </sheetViews>
      <sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0.25"/>
      <sheetData>
        <row r="1" spans="1:19" x14ac:dyDescent="0.25">
          <c r="A1" t="s">
            <v>0</v>
          </c>
          <c r="B1" t="s">
            <v>1</v>
          </c>
          <c r="C1" t="s">
            <v>2</v>
          </c>
       </row>
       ...
     </sheetData>
     <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
    </worksheet>
    Le contenu n'est pas vraiment le même. J'ai tenté de changer les namespaces, rien à faire (dans le fichier réparé, des shared strings sont utilisées mais ça ne m'intéresse pas).
    J'ai tenté de trouver une solution mais rien à faire.
    Les styles ne m'intéressent pas (sauf peut être l'ajustement automatique des colonnes).

    Je souhaiterai juste pouvoir créer un fichier excel bien sans erreurs.

    Ai-je une erreur ou oublié quelque chose dans mon code ?

    Merci.

  2. #2
    Membre averti
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Novembre 2014
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2014
    Messages : 196
    Points : 331
    Points
    331
    Par défaut
    Il y as une déclaration de trois namespace dans le fichier réparer, notamment celui des relations (r) , a mon avis c'est la que sa pêche ... Recherche dans le fichier corrigé si se Namespace est utilisé et si oui comment. Ensuite essaye de reproduire les parties incriminé dans ta génération. C'est juste des piste ....

    Si ton fichier n'est pas nom plus énorme tu peut aussi écrire du XML direct sans passer par OpenXml dans se cas tu as une maîtrise totale du XML.

  3. #3
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut
    Bonjour,

    Je rencontre le même problème.
    A-t-il été résolu ?

    Si oui, je veux bien une astuce...

    Voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
                    SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(chemExcel, SpreadsheetDocumentType.Workbook); // L'avantage de cette API est que l'on peut travailler en flux.
                    WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
                    var wb = new Workbook();
                    wb.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                    wb.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
                    workbookpart.Workbook = wb;
                    WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
                    worksheetPart.Worksheet = new Worksheet(new SheetData());
                    Sheets sheets = new Sheets();
                    Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = (UInt32Value)1U, Name = "Opérations" }; //, Id = "R71b609d3bfb541ee"
                    uint rowIndex = 1;
                    foreach (var item in OpesTmp.items) {
                        Cell cell = Classes.clsExcel.InsertCellInWorksheet("B", rowIndex++, worksheetPart);
                        cell.CellValue = new CellValue(item.source.Name);
                    }
                    sheets.Append(sheet);
                    wb.Append(sheets);
                    spreadsheetDocument.WorkbookPart.Workbook.Save();
                    spreadsheetDocument.Close(); // */
                    chemExcel = string.Empty;
    Mais le résultat n'est pas trop W3C:

    PK  °N0G¨Ýœã s   xl/workbook.xml ¢ (* MRÃ0 …¯âѾuÒé™$Ý°aÅ 7p¥ñ$²=²áHœ Ä0)ÐmwOzšOOúzÿ(O3â9g+È״ڵƞ+˜b·:©.çâÅñÐ87ˆ4oCÁô1úBÊ*{$ÖΣM^ç˜TL%Ÿ¥ë:£ñÞé‰ÐF¹É²½dUL»Bo|€_é[p¤x˜üJ;ò јÑÄ×ú‡™o¡ϨÚÐ#F/™H ?G.Ýð¯„U„<úÏ7¾„±mz.LOùþpÈ·wz×4»íæØ€u)¯4yý^ý
    PK
    °N0GÅ|èW( (  _rels/.rels ¢ (* <?xml version="1.0" encoding="utf-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="/xl/workbook.xml" Id="Rff23d097b2f14780" /></Relationships>PK  °N0Gÿý¦®/ –   xl/worksheets/sheet.xml ¢ (* “ßnƒ Æ_…x¿¢¶µÖX›mfÉúçnÙ=AT6hÍ^m{¤½ÂÄÙolׄßÇ9ççë;ܶe"$ålc93Û„ažP–m¬Z¥w¾µÂ68qñ.sBè &ƒvcåJU„ç¤DrÆ+º³”‹©n)2(+APÒce]Ûö`‰(³´`¿#…ôBðÝõý ÖéÃ_ÞD¼Æ¼©*Š„PoêˆûØ‘†€k¸#innpó;ö»ã!ÞمÁ.6F
    M¦±¥-ÏV ¦€Hj”ž$¯¾ðlÏÐòþie°«³ýû×çXù'ý¨/Üí¼?ð/Úû5Æ×¼`–goý˜FÛ,ûçΨÜnª7Ç,8ǽÞ5 4ú+úPK  °N0G›Î$» +   xl/_rels/workbook.xml.rels ¢ (* Ï;Â0 à«DÞ©ÛŠ·švaaE½@šºµM¢$¼ÎÆÀ‘¸ 10Yöo’·{V\¦‘Ⱥ^+I#%uÝ«–ÃÑ7³5yv*Qø°áºÞ8N”ãÐyo¶ˆNv4 iC*$¶“ð¡µ-!Ѧq¼DûiÀ·ÉÊ«¡DÝ4½¤–lj”ÿãYÛÁuDX)lKž^Æ÷Øá«D¶¯9’åj•Ì7rQU‹yº®€ažá×ËùPK  °N0Gë'ŒŒí Ü   [Content_Types].xml ¢ (* *‘=NÄ0…¯b¹E±B(É@ \`äLký'Ïd g£àH\o‚R $*Ëž÷Þ73þ|ÿh‹wâ„™l *¼TµLìm[9óPÝÈC×¼¼%$Q¤Z91§[*ÉLèTLJeˆÙ—kus„õU]_kcàŠÏ²kîq€Ù±xXÊó†-v)î6ÝÕJHÉY\Êúú*ƒ5ØG3ûbQ”2BO"{§ÖSy°áb
    Ö¿23:úô{*Uœ«†&›hG<•%fÛ£x†ÌàKž^œ~ù¸6DzëëgÝã÷>ôúWÝPK-   °N0G¨Ýœã s  xl/workbook.xmlPK-
    °N0GÅ|èW( ( , _rels/.relsPK-   °N0Gÿý¦®/ –  ™ xl/worksheets/sheet.xmlPK-   °N0G›Î$» +   xl/_rels/workbook.xml.relsPK-   °N0Gë'ŒŒí Ü  ( [Content_Types].xmlPK   D b
    David.

  4. #4
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 064
    Points : 420
    Points
    420
    Par défaut
    Bon, j'ai réussi à parvenir à mes fins avec un vieux post d'un acharné du OpenXml qui a rédéfini toutes les méthodes:
    http://www.developpez.net/forums/d15...bleme-openxml/

    Merci à lui.

    Mais je suis surprit de la quantité de choses à refaire alors qu'on utilise une API. 0_0
    David.

Discussions similaires

  1. Créer un jeu de plate-forme avec Construct 2
    Par s0h3ck dans le forum Développement 2D, 3D et Jeux
    Réponses: 1
    Dernier message: 24/08/2014, 22h40
  2. Créer un fichier .x et générer avec RPCGEN
    Par tululululu dans le forum C
    Réponses: 0
    Dernier message: 01/06/2010, 14h11
  3. Réponses: 5
    Dernier message: 27/05/2008, 15h29
  4. [XML] Créer un fichier sur le serveur avec le contenu d'une requête POST
    Par kingmandrax dans le forum Bibliothèques et frameworks
    Réponses: 10
    Dernier message: 27/10/2006, 00h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo