Gestion de la compatibilité des versions Excel
L'une des erreurs les plus fréquentes lors de l'utilisation de NPOI est la OfficeXmlFileException. Cela se produit généralement lorsqu'on tente d'ouvrir un fichier .xlsx (format XML moderne) avec la classe HSSFWorkbook, qui est exclusivement réservée aux enciens formats .xls (Excel 97-2003).
Pour assurer une compatibilité optimale, il est recommandé d'utiliser l'interface IWorkbook et de détecter le type de fichier ou d'utiliser la classe WorkbookFactory pour une ouverture automatique :
// Approche générique pour supporter .xls et .xlsx
using (FileStream flux = new FileStream(cheminFichier, FileMode.Open, FileAccess.Read))
{
IWorkbook monClasseur = WorkbookFactory.Create(flux);
// Traitement du classeur...
}
Lecture de cellules contenant des formules
Pour extraire le résultat calculé d'une cellule contenant une formule plutôt que la formule elle-même, il est indispensable d'utiliser un évaluateur. Voici comment procéder pour récupérer une valeur numérique ou textuelle après calcul :
public static void ExtraireValeursCalculees(string cheminSource)
{
using (FileStream fs = File.Open(cheminSource, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
XSSFWorkbook classeur = new XSSFWorkbook(fs);
XSSFFormulaEvaluator evaluateur = new XSSFFormulaEvaluator(classeur);
ISheet feuille = classeur.GetSheetAt(0);
// Cibler une cellule spécifique (ex: ligne 10, colonne 2)
ICell celluleCible = feuille.GetRow(9)?.GetCell(1);
if (celluleCible != null && celluleCible.CellType == CellType.Formula)
{
var resultat = evaluateur.Evaluate(celluleCible);
if (resultat.CellType == CellType.Numeric)
{
double valeurNum = resultat.NumberValue;
Console.WriteLine($"Résultat numérique : {valeurNum}");
}
else if (resultat.CellType == CellType.String)
{
string valeurTexte = resultat.StringValue;
Console.WriteLine($"Résultat texte : {valeurTexte}");
}
}
}
}
Forcer le recalcul des formules à l'ouverture
Il arrive que les valeurs calculées ne se mettent pas à jour automatiquement lors de la modification des données sources via NPOI. Pour forcer Excel à recalculer toutes les formules lors de l'ouverture du fichier par l'utilisateur final, utilisez la propriété suivante :
ISheet maFeuille = monClasseur.GetSheetAt(0);
// Active le recalcul automatique des formules
maFeuille.ForceFormulaRecalculation = true;
Ajustement de la mise en page et des colonnes
Le contrôle de l'affichage est crucial pour générer des rapports lisibles. NPOI permet d'ajusetr dynamiquement la largeur des colonnes et l'échelle d'impression.
public static void AjusterFormat(ISheet feuille, int nombreColonnes)
{
// Redimensionnement automatique de chaque colonne
for (int i = 0; i < nombreColonnes; i++)
{
feuille.AutoSizeColumn(i);
}
// Configuration de l'impression : mise à l'échelle (ex: 85%)
feuille.PrintSetup.Scale = 85;
// Pour adapter tout le contenu sur une seule page en largeur :
// feuille.FitToPage = true;
// feuille.PrintSetup.FitWidth = 1;
// feuille.PrintSetup.FitHeight = 0;
}
Sécurisation de l'accès aux lignes et cellules (Prévention des NullReferenceException)
Une erreur classique consiste à accéder à une ligne ou une cellule qui n'a jamais été initialisée dans le fichier Excel. Il est nécessaire de vérifier la nullité et de créer l'objet si besoin.
public void TraitementSecurise(ISheet feuille)
{
int totalLignes = feuille.LastRowNum;
for (int i = 0; i <= totalLignes; i++)
{
IRow ligneActuelle = feuille.GetRow(i) ?? feuille.CreateRow(i);
// Accès à une cellule spécifique avec création si inexistante
int indexCellule = 1; // Colonne B
ICell cellule = ligneActuelle.GetCell(indexCellule) ?? ligneActuelle.CreateCell(indexCellule);
cellule.SetCellValue("Donnée mise à jour");
// Application d'un style de couleur
ICellStyle styleAlerte = feuille.Workbook.CreateCellStyle();
styleAlerte.FillForegroundColor = IndexedColors.Yellow.Index;
styleAlerte.FillPattern = FillPattern.SolidForeground;
cellule.CellStyle = styleAlerte;
}
}
Lors de l'enregistrement, l'utilisation d'un MemoryStream peut s'avérer utile pour manipuler les données en mémoire avant de les persister sur le disque via un FileStream.