Passer au contenu du pied de page
UTILISATION D'IRONXL

Comment créer un tableau croisé dynamique Excel en C#

La génération de tableaux croisés dynamiques par programmation dans Excel nécessite soit C# Interop avec ses dépendances Office, soit des bibliothèques modernes comme IronXL qui fonctionnent de manière indépendante. Ce tutoriel démontre les deux approches, soulignant pourquoi les développeurs choisissent de plus en plus IronXL par rapport aux méthodes traditionnelles Interop.

Dans cet article, nous apprendrons comment éditer, créer, concevoir et calculer des tableaux croisés dynamiques et des groupes, avec analyse automatique et gestion des erreurs.

Qu'est-ce qu'un tableau croisé dynamique Excel ?

Un type pivot est l'un des outils les plus puissants que vous puissiez ajouter dans Excel. C'est un moyen facile et simple de résumer de grands ensembles de données. Par conséquent, les tableaux croisés dynamiques vous permettent d'afficher, de comprendre et d'analyser facilement des données numériques. Les tableaux croisés dynamiques sont disponibles non seulement dans Excel mais aussi dans d'autres programmes tels que Google Sheets, Apple Numbers et les exportations CSV. Il fournit une solution pour voir les données en vue d'ensemble - Agissant comme une console de données pour permettre aux gens de voir leurs informations de manière significative - en lien avec la réalité.

Faisons un tableau croisé dynamique de manière incorrecte puis apprenons à le faire correctement en C# :

Comment créer un tableau croisé dynamique dans les tableaux Excel en utilisant C# Interop ?

C# Excel Interop fournit un accès direct à la fonctionnalité de tableau croisé dynamique d'Excel via l'automatisation COM. Voici l'approche traditionnelle que de nombreux développeurs trouvent lorsqu'ils recherchent un outil pour générer un tableau croisé dynamique en C# : (Déprécié)

Comment créer des tableaux croisés dynamiques à l'ancienne dans .NET

using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
// Create Excel application instance
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Data\SalesData.xlsx");
Excel.Worksheet xlSheet = (Excel.Worksheet)xlWorkbook.Sheets[1];
Excel.Worksheet xlPivotSheet = (Excel.Worksheet)xlWorkbook.Sheets.Add();
// Define data range for pivot table
Excel.Range dataRange = xlSheet.UsedRange;
// Row area and column area 
// Create pivot cache and pivot table
Excel.PivotCache pivotCache = xlWorkbook.PivotCaches().Create(
    Excel.XlPivotTableSourceType.xlDatabase,
    dataRange,
    Type.Missing);
Excel.PivotTable pivotTable = pivotCache.CreatePivotTable(
    xlPivotSheet.Cells[3, 1],
    "SalesPivot",
    Type.Missing,
    Type.Missing); // fields by field
// Configure pivot table fields
Excel.PivotField productField = (Excel.PivotField)pivotTable.PivotFields("Product");
productField.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
productField.Position = 1;
Excel.PivotField regionField = (Excel.PivotField)pivotTable.PivotFields("Region");
regionField.Orientation = Excel.XlPivotFieldOrientation.xlColumnField;
regionField.Position = 1;
Excel.PivotField salesField = (Excel.PivotField)pivotTable.PivotFields("Sales");
pivotTable.AddDataField(salesField, "Sum of Sales", Excel.XlConsolidationFunction.xlSum);
// Save and cleanup
xlWorkbook.SaveAs(@"C:\Data\PivotReport.xlsx");
xlWorkbook.Close();
xlApp.Quit();
// Release COM objects to prevent memory leaks
Marshal.ReleaseComObject(pivotTable);
Marshal.ReleaseComObject(pivotCache);
Marshal.ReleaseComObject(xlPivotSheet);
Marshal.ReleaseComObject(xlSheet);
Marshal.ReleaseComObject(xlWorkbook);
Marshal.ReleaseComObject(xlApp);
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
// Create Excel application instance
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Data\SalesData.xlsx");
Excel.Worksheet xlSheet = (Excel.Worksheet)xlWorkbook.Sheets[1];
Excel.Worksheet xlPivotSheet = (Excel.Worksheet)xlWorkbook.Sheets.Add();
// Define data range for pivot table
Excel.Range dataRange = xlSheet.UsedRange;
// Row area and column area 
// Create pivot cache and pivot table
Excel.PivotCache pivotCache = xlWorkbook.PivotCaches().Create(
    Excel.XlPivotTableSourceType.xlDatabase,
    dataRange,
    Type.Missing);
Excel.PivotTable pivotTable = pivotCache.CreatePivotTable(
    xlPivotSheet.Cells[3, 1],
    "SalesPivot",
    Type.Missing,
    Type.Missing); // fields by field
// Configure pivot table fields
Excel.PivotField productField = (Excel.PivotField)pivotTable.PivotFields("Product");
productField.Orientation = Excel.XlPivotFieldOrientation.xlRowField;
productField.Position = 1;
Excel.PivotField regionField = (Excel.PivotField)pivotTable.PivotFields("Region");
regionField.Orientation = Excel.XlPivotFieldOrientation.xlColumnField;
regionField.Position = 1;
Excel.PivotField salesField = (Excel.PivotField)pivotTable.PivotFields("Sales");
pivotTable.AddDataField(salesField, "Sum of Sales", Excel.XlConsolidationFunction.xlSum);
// Save and cleanup
xlWorkbook.SaveAs(@"C:\Data\PivotReport.xlsx");
xlWorkbook.Close();
xlApp.Quit();
// Release COM objects to prevent memory leaks
Marshal.ReleaseComObject(pivotTable);
Marshal.ReleaseComObject(pivotCache);
Marshal.ReleaseComObject(xlPivotSheet);
Marshal.ReleaseComObject(xlSheet);
Marshal.ReleaseComObject(xlWorkbook);
Marshal.ReleaseComObject(xlApp);
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Cet exemple Interop crée un tableau croisé dynamique XL natif avec le produit en tant que lignes, la région en tant que colonnes et les ventes résumées dans la zone de données. Bien que fonctionnelle, cette approche nécessite l'installation de Microsoft Office et une gestion attentive des objets COM. Consultez la documentation Microsoft sur les raisons pour lesquelles cette approche n'est pas moderne.

Quels problèmes C# Interop crée-t-il ?

L'approche Interop présente plusieurs défis importants :

Malheureusement, Stack Overflow et d'autres sites Web de programmation continuent de la recommander car ils sont enfermés dans le temps avec des fils verrouillés sur des idées du début des années 2000.

Dépendances de déploiement : nécessite l'installation de Microsoft Office sur chaque machine exécutant le code source, y compris les serveurs de production. Cela ajoute des coûts de licence et une complexité de déploiement.

Gestion de la mémoire : les objets COM doivent être explicitement libérés en utilisant Marshal.ReleaseComObject(). Oublier ne serait-ce qu'un seul objet provoque le blocage des processus Excel en mémoire, comme documenté de manière approfondie sur Stack Overflow. Considérez le cache pivot.

Détails des limitations de plateforme : cette solution à l'ancienne ne fonctionne que sur Windows avec Office installé. Et cela peut être incroyablement lent - déroutant pour l'utilisateur et peut entraîner des fuites de mémoire. Aucun support pour Linux, macOS, les conteneurs Docker, ou des plateformes cloud comme Azure Functions.

Problèmes de performance : le démarrage des instances d'application Excel est lent et gourmand en ressources, surtout pour le traitement côté serveur.

Compatibilité des versions : les différentes versions d'Office peuvent avoir des interfaces COM variables, causant des problèmes de compatibilité entre les environnements.

Comment IronXL crée-t-il un tableau croisé dynamique par programmation sans Interop ?

IronXL aborde la création de tableaux croisés dynamiques différemment, en utilisant du code géré sans dépendances COM. Bien qu'il ne crée pas de tableaux croisés dynamiques Excel natifs, il offre de puissantes capacités d'agrégation :

Comment créer un tableau croisé dynamique XLSX ou XLS par programmation de manière moderne :

using IronXL;
using System.Linq;
using System.Data; // Keep this namespace
using static System.Data.DataTableExtensions; // Use 'using static' for DataTableExtensions
class Program
{
    static void Main(string[] args)
    {
        // Load Excel file - no Office required
        WorkBook workbook = WorkBook.Load("SalesData.xlsx");
        WorkSheet dataSheet = workbook.WorkSheets[0];
        // Convert to DataTable for powerful manipulation
        var dataTable = dataSheet.ToDataTable(true); // true = use first row as column headers
        // Create pivot-style aggregation using LINQ
        var pivotData = dataTable.AsEnumerable()
            .GroupBy(row => new {
                Product = row["Product"].ToString(),
                Region = row["Region"].ToString()
            }) //range
            .Select(g => new {
                Product = g.Key.Product,
                Region = g.Key.Region,
                TotalSales = g.Sum(row => Convert.ToDecimal(row["Sales"])),
                AverageSale = g.Average(row => Convert.ToDecimal(row["Sales"])),
                Count = g.Count()
            }); 
        // Create pivot report worksheet
        WorkSheet pivotSheet = workbook.CreateWorkSheet("PivotReport");
        // Build cross-tabulation structure
        var products = pivotData.Select(p => p.Product).Distinct().OrderBy(p => p);
        var regions = pivotData.Select(p => p.Region).Distinct().OrderBy(r => r);
        // Create headers
        pivotSheet["A1"].Value = "Product/Region";
        int col = 2;
        foreach (var region in regions)
        {
            pivotSheet[$"{(char)('A' + col - 1)}1"].Value = region; // string  
            col++;
        }
        // Populate pivot data
        int row = 2;
        foreach (var product in products)
        {
            pivotSheet[$"A{row}"].Value = product;
            col = 2;
            foreach (var region in regions)
            {
                var sales = pivotData
                    .Where(p => p.Product == product && p.Region == region)
                    .Select(p => p.TotalSales)
                    .FirstOrDefault();
                pivotSheet[$"{(char)('A' + col - 1)}{row}"].Value = sales;
                col++;
            }
            row++;
        }
        // Add totals using Excel formulas
        pivotSheet[$"A{row}"].Value = "Total"; // grand totals
        for (int c = 2; c <= regions.Count() + 1; c++)
        {
            pivotSheet[$"{(char)('A' + c - 1)}{row}"].Formula = $"=SUM({(char)('A' + c - 1)}2:{(char)('A' + c - 1)}{row - 1})";
        }
        // Proceeding to apply formatting
        var dataRange = pivotSheet[$"B2:{(char)('A' + regions.Count())}{row}"];
        dataRange.FormatString = "$#,##0.00";
        workbook.SaveAs("PivotReport.xlsx");
    }
}
using IronXL;
using System.Linq;
using System.Data; // Keep this namespace
using static System.Data.DataTableExtensions; // Use 'using static' for DataTableExtensions
class Program
{
    static void Main(string[] args)
    {
        // Load Excel file - no Office required
        WorkBook workbook = WorkBook.Load("SalesData.xlsx");
        WorkSheet dataSheet = workbook.WorkSheets[0];
        // Convert to DataTable for powerful manipulation
        var dataTable = dataSheet.ToDataTable(true); // true = use first row as column headers
        // Create pivot-style aggregation using LINQ
        var pivotData = dataTable.AsEnumerable()
            .GroupBy(row => new {
                Product = row["Product"].ToString(),
                Region = row["Region"].ToString()
            }) //range
            .Select(g => new {
                Product = g.Key.Product,
                Region = g.Key.Region,
                TotalSales = g.Sum(row => Convert.ToDecimal(row["Sales"])),
                AverageSale = g.Average(row => Convert.ToDecimal(row["Sales"])),
                Count = g.Count()
            }); 
        // Create pivot report worksheet
        WorkSheet pivotSheet = workbook.CreateWorkSheet("PivotReport");
        // Build cross-tabulation structure
        var products = pivotData.Select(p => p.Product).Distinct().OrderBy(p => p);
        var regions = pivotData.Select(p => p.Region).Distinct().OrderBy(r => r);
        // Create headers
        pivotSheet["A1"].Value = "Product/Region";
        int col = 2;
        foreach (var region in regions)
        {
            pivotSheet[$"{(char)('A' + col - 1)}1"].Value = region; // string  
            col++;
        }
        // Populate pivot data
        int row = 2;
        foreach (var product in products)
        {
            pivotSheet[$"A{row}"].Value = product;
            col = 2;
            foreach (var region in regions)
            {
                var sales = pivotData
                    .Where(p => p.Product == product && p.Region == region)
                    .Select(p => p.TotalSales)
                    .FirstOrDefault();
                pivotSheet[$"{(char)('A' + col - 1)}{row}"].Value = sales;
                col++;
            }
            row++;
        }
        // Add totals using Excel formulas
        pivotSheet[$"A{row}"].Value = "Total"; // grand totals
        for (int c = 2; c <= regions.Count() + 1; c++)
        {
            pivotSheet[$"{(char)('A' + c - 1)}{row}"].Formula = $"=SUM({(char)('A' + c - 1)}2:{(char)('A' + c - 1)}{row - 1})";
        }
        // Proceeding to apply formatting
        var dataRange = pivotSheet[$"B2:{(char)('A' + regions.Count())}{row}"];
        dataRange.FormatString = "$#,##0.00";
        workbook.SaveAs("PivotReport.xlsx");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Ainsi, en 2025, c'est ainsi que vous créez des tableaux croisés dynamiques.

Sortie

Comment créer un tableau croisé dynamique Excel en C#: Figure 1 - Le fichier Excel d'origine vs. le tableau croisé que nous avons créé montrant les cellules.

Comment créer des résumés dynamiques avec les formules IronXL ?

Pour les scénarios nécessitant des mises à jour dynamiques similaires à créer un tableau croisé dynamique, calculer la fonctionnalité de rafraîchissement du tableau croisé, IronXL peut tirer parti des formules intégrées d'Excel pour obtenir vos réponses. En général, c'est préférable à la réponse précédente - Votre enregistrement est géré de manière beaucoup plus moderne et élégante. Avec le code, une personne peut comprendre facilement. Facile à configurer, sans besoin de contacter le support ou de lire un manuel.

// Load the workbook
WorkBook workbook = WorkBook.Load(inputPath);
// Rename the first worksheet so formulas reference correctly
WorkSheet dataSheet = workbook.WorkSheets[0];
dataSheet.Name = "DataSheet";
// Convert worksheet to DataTable
DataTable dataTable = dataSheet.ToDataTable(true);
// Create new summary worksheet
WorkSheet summarySheet = workbook.CreateWorkSheet("DynamicSummary");
// Get unique product-region combinations
var uniqueCombos = dataTable.AsEnumerable()
    .Select(row => new {
        Product = row["Product"].ToString(),
        Region = row["Region"].ToString()
    })
    .Distinct()
    .OrderBy(x => x.Product)
    .ThenBy(x => x.Region);
// Add header row
summarySheet["A1"].Value = "Product";
summarySheet["B1"].Value = "Region";
summarySheet["C1"].Value = "Total Sales";
summarySheet["D1"].Value = "Count";
// Populate rows with formulas
int rowIndex = 2;
foreach (var combo in uniqueCombos)
{
    summarySheet[$"A{rowIndex}"].Value = combo.Product;
    summarySheet[$"B{rowIndex}"].Value = combo.Region;
    // Adjust column references if your Sales column is C (not D)
    summarySheet[$"C{rowIndex}"].Formula =
        $"=SUMIFS(DataSheet!C:C,DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    summarySheet[$"D{rowIndex}"].Formula =
        $"=COUNTIFS(DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    rowIndex++;
}
// Optional: add total row
summarySheet[$"A{rowIndex}"].Value = "Total";
summarySheet[$"C{rowIndex}"].Formula = $"=SUM(C2:C{rowIndex - 1})";
summarySheet[$"D{rowIndex}"].Formula = $"=SUM(D2:D{rowIndex - 1})";
// Save output file
workbook.SaveAs(outputPath);  //filename
// Load the workbook
WorkBook workbook = WorkBook.Load(inputPath);
// Rename the first worksheet so formulas reference correctly
WorkSheet dataSheet = workbook.WorkSheets[0];
dataSheet.Name = "DataSheet";
// Convert worksheet to DataTable
DataTable dataTable = dataSheet.ToDataTable(true);
// Create new summary worksheet
WorkSheet summarySheet = workbook.CreateWorkSheet("DynamicSummary");
// Get unique product-region combinations
var uniqueCombos = dataTable.AsEnumerable()
    .Select(row => new {
        Product = row["Product"].ToString(),
        Region = row["Region"].ToString()
    })
    .Distinct()
    .OrderBy(x => x.Product)
    .ThenBy(x => x.Region);
// Add header row
summarySheet["A1"].Value = "Product";
summarySheet["B1"].Value = "Region";
summarySheet["C1"].Value = "Total Sales";
summarySheet["D1"].Value = "Count";
// Populate rows with formulas
int rowIndex = 2;
foreach (var combo in uniqueCombos)
{
    summarySheet[$"A{rowIndex}"].Value = combo.Product;
    summarySheet[$"B{rowIndex}"].Value = combo.Region;
    // Adjust column references if your Sales column is C (not D)
    summarySheet[$"C{rowIndex}"].Formula =
        $"=SUMIFS(DataSheet!C:C,DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    summarySheet[$"D{rowIndex}"].Formula =
        $"=COUNTIFS(DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    rowIndex++;
}
// Optional: add total row
summarySheet[$"A{rowIndex}"].Value = "Total";
summarySheet[$"C{rowIndex}"].Formula = $"=SUM(C2:C{rowIndex - 1})";
summarySheet[$"D{rowIndex}"].Formula = $"=SUM(D2:D{rowIndex - 1})";
// Save output file
workbook.SaveAs(outputPath);  //filename
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Ces formules maintiennent des connexions actives aux données source, se mettant à jour automatiquement lorsque la feuille de données change - similaire au comportement de rafraîchissement des tableaux croisés mais sans les dépendances Interop.

Si nous appliquons ce code à l'exemple de fichier Excel (XLS / XLSX) de l'exemple précédent, nous obtiendrions cette sortie de champs sur la page :

Comment créer un tableau croisé dynamique Excel en C#: Figire 2 - Note: Sorties de résumés dynamiques C# semblent en contexte de localisation.

Comparer C# Interop et IronXL pour les tableaux croisés dynamiques

Aspect

C# Interop

IronXL

Office Requis

Oui - Installation complète

Non - Bibliothèque autonome

Support de plateforme

Windows seulement

Windows, Linux, macOS, Docker

Gestion de la mémoire

Nettoyage manuel des COM requis

Collecte des ordures .NET automatique

Déploiement

Complexe - Licences Office

Simple - DLL unique

Performance

Lent - Démarrage du processus Excel

Rapide - Calculs en mémoire

Compatible Cloud

Non - Limitations Azure

Oui - Support des Fonctions Azure

Tableaux Croisés Dynamiques Natifs

Oui

Non - Alternatives d'agrégation

Vitesse de Développement

Lent - Complexité COM

Rapide - API intuitif

Quelle approche devriez-vous choisir ?

Choisissez C# Interop lorsque :

  • Les objets de tableau croisé dynamique Excel natifs sont absolument nécessaires
  • Vous travaillez exclusivement sur Windows avec Office installé sur chaque machine cible
  • Vous ne déployez que sur des systèmes de bureau que vous administrez
  • Le code existant hérité dépend de l'Interop
  • Vous utilisez une version héritée de .NET Framework

Choisissez IronXL lorsque :

  • Vous déployez sur des serveurs ou des environnements et services cloud (Azure, AWS ...)
  • Vous développez des applications multiplateformes
  • Vous nécessitez de meilleures performances et une meilleure fiabilité
  • Vous évitez les coûts de licence Office
  • Vous nécessitez un code plus simple et plus maintenable
  • Vous supportez les systèmes Mac, iOS, Android et/ou Linux
  • Vous travaillez dans les versions modernes de .NET Framework Core et .NET 5,6,7,8,9,10
  • Vous voulez un accès complet dans votre console de développement / IDE pour configurer les paramètres pour chaque champ du tableau croisé dynamique à partir de vos plages de données.

Conclusion

Bien que C# Excel Interop puisse développer des tableaux croisés dynamiques natifs, ses restrictions de déploiement et sa complexité le rendent de plus en plus impraticable pour les applications modernes. IronXL fournit de puissantes alternatives à travers l'agrégation des données et les résumés basés sur des formules, éliminant les dépendances Office tout en maintenant des capacités analytiques. Veuillez voter, commenter ou vous abonner si cela a été utile.

Pour les développeurs à la recherche d'une option alternative pour développer des tableaux croisés dynamiques sans Interop, IronXL offre un chemin supérieur qui évite les complications COM, fonctionne sur toutes les plateformes, et simplifie le déploiement. Le compromis de ne pas avoir d'objets de tableau croisé natifs est compensé par une plus grande flexibilité, de meilleures performances, et l'élimination des exigences de licence Office.

Commencez avec IronXL maintenant.
green arrow pointer

Prêt à moderniser votre automatisation Excel et créer votre propre code de tableau croisé dynamique en C# moderne ?

IronXL peut être implémenté dans vos applications C# en quelques secondes via le gestionnaire de packages NuGet. Essayez l'essai gratuit pour éliminer les dépendances Interop dans vos applications de production.

Questions Fréquemment Posées

Qu'est-ce qu'un tableau croisé dynamique dans Excel ?

Un tableau croisé dynamique dans Excel est un outil puissant utilisé pour résumer, analyser, explorer et présenter les données. Il permet aux utilisateurs de transformer les colonnes en lignes et inversement, permettant une analyse dynamique des données.

Pourquoi utiliser IronXL pour créer des tableaux croisés dynamiques Excel en C# ?

IronXL permet aux développeurs de créer des tableaux croisés dynamiques Excel en C# sans dépendre de l’Interop de Office, éliminant le besoin d'installations Excel et réduisant les dépendances, ce qui en fait un choix moderne et efficace.

Comment IronXL se compare-t-il à l'Interop C# pour les opérations Excel ?

IronXL offre une approche plus simplifiée et indépendante par rapport à l'Interop C#, qui nécessite des installations Office. IronXL simplifie la création de tableaux croisés dynamiques et d'autres opérations Excel sans les complications d'Interop.

Puis-je générer des tableaux croisés dynamiques sans Excel installé ?

Oui, en utilisant IronXL, vous pouvez générer des tableaux croisés dynamiques dans vos applications C# sans avoir Excel installé, car il fonctionne indépendamment de Microsoft Office.

IronXL est-il adapté aux grands ensembles de données ?

IronXL est conçu pour gérer efficacement de grands ensembles de données, le rendant adapté aux applications nécessitant une manipulation robuste des données et la génération de tableaux croisés dynamiques.

Quels sont les avantages d'utiliser IronXL par rapport aux méthodes traditionnelles ?

IronXL fournit une alternative moderne et sans dépendance aux méthodes traditionnelles comme l'Interop C#, offrant une facilité d'utilisation, flexibilité, et support pour des opérations complexes de données sans besoin d'installations Excel.

Dois-je apprendre VBA pour utiliser IronXL pour les tableaux croisés dynamiques ?

Non, IronXL permet aux développeurs de travailler directement dans C# pour créer et gérer des tableaux croisés dynamiques, éliminant le besoin d'apprendre VBA ou d'autres langages de programmation spécifiques à Excel.

Jordi Bardia
Ingénieur logiciel
Jordi est le plus compétent en Python, C# et C++, et lorsqu'il ne met pas à profit ses compétences chez Iron Software, il programme des jeux. Partageant les responsabilités des tests de produit, du développement de produit et de la recherche, Jordi apporte une immense valeur à l'amé...
Lire la suite