Obtenir un en-tête de colonne dans un document de feuille de calcul
Cette rubrique montre comment utiliser les classes du Kit de développement logiciel (SDK) Open XML pour Office afin de récupérer un en-tête de colonne dans un document de feuille de calcul par programmation.
Structure de base d’un document spreadsheetML
La structure de base d’un SpreadsheetML
document se compose des Sheets éléments et Sheet , qui font référence aux feuilles de calcul du classeur. Un fichier XML distinct est créé pour chaque feuille de calcul. Par exemple, le SpreadsheetML
pour un Workbook qui a deux feuilles de calcul nommées MySheet1 et MySheet2 se trouve dans le fichier Workbook.xml et est illustré dans l’exemple de code suivant.
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<sheets>
<sheet name="MySheet1" sheetId="1" r:id="rId1" />
<sheet name="MySheet2" sheetId="2" r:id="rId2" />
</sheets>
</workbook>
Les fichiers XML de feuille de calcul contiennent un ou plusieurs éléments de niveau bloc, tels que SheetData représente la table de cellules et contient un ou plusieurs Row éléments. Un row
contient un ou plusieurs Cell éléments. Chaque cellule contient un CellValue élément qui représente la valeur de la cellule. Par exemple, le SpreadsheetML
pour la première feuille de calcul d’un classeur, qui n’a que la valeur 100 dans la cellule A1, se trouve dans le fichier Sheet1.xml et est illustré dans l’exemple de code suivant.
<?xml version="1.0" encoding="UTF-8" ?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<sheetData>
<row r="1">
<c r="A1">
<v>100</v>
</c>
</row>
</sheetData>
</worksheet>
À l’aide du Kit de développement logiciel (SDK) Open XML, vous pouvez créer une structure de document et un contenu qui utilisent des classes fortement typées qui correspondent à SpreadsheetML
des éléments. Vous trouverez ces classes dans l’espace de DocumentFormat.OpenXML.Spreadsheet
noms . Le tableau suivant répertorie les noms de classes des classes qui correspondent aux workbook
éléments , sheets
, sheet
, worksheet
et sheetData
.
Élément SpreadsheetML | Classe du Kit de développement logiciel (SDK) Open XML | Description |
---|---|---|
<workbook/> |
DocumentFormat.OpenXML.Spreadsheet.Workbook | Élément racine du composant document principal. |
<sheets/> |
DocumentFormat.OpenXML.Spreadsheet.Sheets | Conteneur des structures de niveau bloc comme les éléments de feuille, fileVersion et autres spécifiés par la norme ISO/IEC 29500. |
<sheet/> |
DocumentFormat.OpenXml.Spreadsheet.Sheet | Feuille qui pointe vers un fichier de définition de feuille. |
<worksheet/> |
DocumentFormat.OpenXML.Spreadsheet. Feuilles de calcul | Fichier de définition de feuille qui contient les données de feuille. |
<sheetData/> |
DocumentFormat.OpenXML.Spreadsheet.SheetData | Tableau de cellules, regroupées par lignes. |
<row/> |
DocumentFormat.OpenXml.Spreadsheet.Row | Ligne dans le tableau de cellules. |
<c/> |
DocumentFormat.OpenXml.Spreadsheet.Cell | Cellule d'une ligne. |
<v/> |
DocumentFormat.OpenXml.Spreadsheet.CellValue | Valeur d’une cellule. |
Fonctionnement de l’exemple de code
Le code de ce guide pratique se compose de trois méthodes (fonctions en Visual Basic) : GetColumnHeading
, GetColumnName
et GetRowIndex
. Les deux dernières méthodes sont appelées à partir de la GetColumnHeading
méthode .
La GetColumnName
méthode prend le nom de la cellule en tant que paramètre. Elle analyse le nom de la cellule pour obtenir le nom de la colonne en créant une expression régulière pour trouver le nom de la colonne dans le nom de la cellule. Pour en savoir plus sur les expressions régulières, consultez l’article Langage des expressions régulières - Aide-mémoire.
// Create a regular expression to match the column name portion of the cell name.
Regex regex = new Regex("[A-Za-z]+");
Match match = regex.Match(cellName);
return match.Value;
La GetRowIndex
méthode prend le nom de la cellule en tant que paramètre. Elle analyse ce nom pour obtenir l'index de la ligne en créant une expression régulière pour trouver la partie index de ligne du nom de la cellule.
// Create a regular expression to match the row index portion the cell name.
Regex regex = new Regex(@"\d+");
Match match = regex.Match(cellName);
return uint.Parse(match.Value);
La GetColumnHeading
méthode utilise trois paramètres : le chemin d’accès complet au fichier de feuille de calcul source, le nom de la feuille de calcul qui contient la colonne spécifiée et le nom d’une cellule dans la colonne pour laquelle obtenir le titre.
Le code obtient le nom de la colonne de la cellule spécifiée en appelant la GetColumnName
méthode . Le code obtient également les cellules de la colonne et les trie par ligne à l’aide de la GetRowIndex
méthode .
// Get the column name for the specified cell.
string columnName = GetColumnName(cellName);
// Get the cells in the specified column and order them by row.
IEnumerable<Cell> cells = worksheetPart.Worksheet.Descendants<Cell>().Where(c => string.Compare(GetColumnName(c.CellReference?.Value), columnName, true) == 0)
.OrderBy(r => GetRowIndex(r.CellReference) ?? 0);
Si la colonne spécifiée existe, elle obtient la première cellule de la colonne à l’aide de la First méthode . La première cellule contient l'en-tête. Sinon, la colonne spécifiée n’existe pas et la méthode retourne null
/ Nothing
if (cells.Count() == 0)
{
// The specified column does not exist.
return null;
}
// Get the first cell in the column.
Cell headCell = cells.First();
Si le contenu de la cellule est stocké dans l’objet SharedStringTablePart , elle obtient les éléments de chaîne partagés et retourne le contenu de l’en-tête de colonne à l’aide de la Parse méthode . Si le contenu de la cellule n’est pas dans l’objet SharedStringTable , elle retourne le contenu de la cellule.
// If the content of the first cell is stored as a shared string, get the text of the first cell
// from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
if (headCell.DataType is not null && headCell.DataType.Value == CellValues.SharedString && int.TryParse(headCell.CellValue?.Text, out int index))
{
SharedStringTablePart shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
SharedStringItem[] items = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
return items[index].InnerText;
}
else
{
return headCell.CellValue?.Text;
}
Exemple de code
Voici un exemple de code complet en C# et Visual Basic.
static string? GetColumnHeading(string docName, string worksheetName, string cellName)
{
// Open the document as read-only.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, false))
{
IEnumerable<Sheet>? sheets = document.WorkbookPart?.Workbook.Descendants<Sheet>().Where(s => s.Name == worksheetName);
if (sheets is null || sheets.Count() == 0)
{
// The specified worksheet does not exist.
return null;
}
string? id = sheets.First().Id;
if (id is null)
{
// The worksheet does not have an ID.
return null;
}
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart!.GetPartById(id);
// Get the column name for the specified cell.
string columnName = GetColumnName(cellName);
// Get the cells in the specified column and order them by row.
IEnumerable<Cell> cells = worksheetPart.Worksheet.Descendants<Cell>().Where(c => string.Compare(GetColumnName(c.CellReference?.Value), columnName, true) == 0)
.OrderBy(r => GetRowIndex(r.CellReference) ?? 0);
if (cells.Count() == 0)
{
// The specified column does not exist.
return null;
}
// Get the first cell in the column.
Cell headCell = cells.First();
// If the content of the first cell is stored as a shared string, get the text of the first cell
// from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
if (headCell.DataType is not null && headCell.DataType.Value == CellValues.SharedString && int.TryParse(headCell.CellValue?.Text, out int index))
{
SharedStringTablePart shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
SharedStringItem[] items = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
return items[index].InnerText;
}
else
{
return headCell.CellValue?.Text;
}
}
}
// Given a cell name, parses the specified cell to get the column name.
static string GetColumnName(string? cellName)
{
if (cellName is null)
{
return string.Empty;
}
// Create a regular expression to match the column name portion of the cell name.
Regex regex = new Regex("[A-Za-z]+");
Match match = regex.Match(cellName);
return match.Value;
}
// Given a cell name, parses the specified cell to get the row index.
static uint? GetRowIndex(string? cellName)
{
if (cellName is null)
{
return null;
}
// Create a regular expression to match the row index portion the cell name.
Regex regex = new Regex(@"\d+");
Match match = regex.Match(cellName);
return uint.Parse(match.Value);
}