2010-06-24 5 views
5

J'utilise openxml pour créer un rapport Excel. L'openxml fonctionne sur un fichier modèle Excel en utilisant des plages nommées.openxml - insertion d'une ligne, déplacement des autres

Le client requiert une ligne de totaux à la fin de la liste des lignes. Cela ressemble à une demande raisonnable !!

Cependant, la table de données que je rentre de la base de données peut contenir n'importe quel nombre de lignes. En utilisant les lignes de modèle et 'InsertBeforeSelf', ma ligne de totaux est surchargée.

Ma question est, en utilisant openxml, comment puis-je insérer des lignes dans la feuille de calcul, provoquant le déplacement de la rangée des totaux chaque fois qu'une ligne est insérée?

Cordialement ...

Répondre

7

En supposant que vous utilisez le SDK 2.0, je l'ai fait quelque chose de similaire en utilisant cette fonction:

private static Row CreateRow(Row refRow, SheetData sheetData) 
    { 
     uint rowIndex = refRow.RowIndex.Value; 
     uint newRowIndex; 
     var newRow = (Row)refRow.Clone(); 

     /*IEnumerable<Row> rows = sheetData.Descendants<Row>().Where(r => r.RowIndex.Value >= rowIndex); 
     foreach (Row row in rows) 
     { 
      newRowIndex = System.Convert.ToUInt32(row.RowIndex.Value + 1); 

      foreach (Cell cell in row.Elements<Cell>()) 
      { 
       string cellReference = cell.CellReference.Value; 
       cell.CellReference = new StringValue(cellReference.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString())); 
      } 

      row.RowIndex = new UInt32Value(newRowIndex); 
     }*/ 

     sheetData.InsertBefore(newRow, refRow); 
     return newRow; 
    } 

Je ne sais pas comment vous le faisiez avec InsertBeforeSelf avant , alors peut-être que ce n'est pas vraiment une amélioration, mais cela a fonctionné pour moi. Je pensais que vous pouviez utiliser votre ligne de totaux comme ligne de référence. (La partie commentée est pour si vous aviez des lignes après votre ligne de référence que vous vouliez maintenir.J'ai fait quelques modifications, mais il vient principalement de ce fil: http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/65c9ca1c-25d4-482d-8eb3-91a3512bb0ac)

Comme il retourne la nouvelle ligne, vous pouvez utiliser cet objet puis d'éditer les valeurs de cellule avec les données de la base de données. J'espère que cela est au moins un peu utile à tous ceux qui essaient de le faire ...

+0

Merci beaucoup! Je cherchais ça !!!! –

+0

Sachez que les cellules de fusion sont conservées dans un objet distinct. Si vous souhaitez conserver le format de fusion correct, vous devez mettre à jour leurs références. S'il vous plaît vérifier http://stackoverflow.com/a/11455088/1099945 – gyosifov

2

[Quelqu'un peut-il avec plus de points s'il vous plaît mettre ce texte comme un commentaire pour la réponse du M_R_H.]

La solution M_R_H a donné a aidé moi, mais introduit un nouveau bug pour le problème. Si vous utilisez la méthode CreateRow donnée telle quelle, si l'une des lignes déplacées/référencées a des formules, CalcChain.xml (dans le package) sera rompue. J'ai ajouté le code suivant à la solution CreateRow proposée. Il ne résout toujours pas le problème, parce que, je pense que ce code est la fixation seule la référence de la ligne actuellement copié-être:

if (cell.CellFormula != null) { 
    string cellFormula = cell.CellFormula.Text; 
    cell.CellFormula = new CellFormula(cellFormula.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString())); 
} 

Quelle est la bonne façon de corriger/mettre à jour CalcChain.xml?

PS: SheetData peut être obtenu à partir de votre feuille de calcul comme:

worksheet.GetFirstChild<SheetData>();