Freigeben über


Einfügen von Text in eine Zelle in einem Tabellenkalkulationsdokument

In diesem Thema wird gezeigt, wie Sie die Klassen im Open XML SDK für Office verwenden, um Text programmgesteuert in eine Zelle in einem neuen Arbeitsblatt in einem Tabellenkalkulationsdokument einzufügen.


Grundlegende Struktur eines SpreadsheetML-Dokuments

Die grundlegende Dokumentstruktur eines SpreadsheetML Dokuments besteht aus den Sheets Elementen und Sheet , die auf die Arbeitsblätter in der Arbeitsmappe verweisen. A separate XML file is created for each worksheet. Beispielsweise befindet sich der SpreadsheetML für ein Workbook mit den beiden Arbeitsblättern MySheet1 und MySheet2 in der Workbook.xml Datei und wird im folgenden Codebeispiel gezeigt.

    <?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>

Die XML-Dateien des Arbeitsblatts enthalten ein oder mehrere Elemente auf Blockebene, z. B. stellt SheetData die Zelltabelle dar und enthält mindestens ein Row Element. Ein row -Element enthält mindestens ein Cell -Element. Jede Zelle enthält ein CellValue Element, das den Wert der Zelle darstellt. Beispielsweise befindet sich das SpreadsheetML für das erste Arbeitsblatt in einer Arbeitsmappe, das nur den Wert 100 in Zelle A1 aufweist, in der Sheet1.xml-Datei und wird im folgenden Codebeispiel gezeigt.

    <?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>

Mit dem Open XML SDK können Sie Dokumentstrukturen und Inhalte erstellen, die stark typisierte Klassen verwenden, die Elementen entsprechen SpreadsheetML . Sie finden diese Klassen im DocumentFormat.OpenXML.Spreadsheet -Namespace. In der folgenden Tabelle sind die Klassennamen der Klassen aufgeführt, die den workbookElementen , sheets, sheet, worksheetund sheetData entsprechen.

SpreadsheetML-Element Open XML SDK-Klasse Beschreibung
<workbook/> DocumentFormat.OpenXML.Spreadsheet.Workbook Das Stammelement des Hauptdokumentteils.
<sheets/> DocumentFormat.OpenXML.Spreadsheet.Sheets Der Container für die Strukturen auf Blockebene, wie z. B. "sheet", "fileVersion" und andere Elemente, die in der Spezifikation ISO/IEC 29500 angegeben sind.
<sheet/> DocumentFormat.OpenXml.Spreadsheet.Sheet Ein Blatt, das auf eine Blattdefinitionsdatei zeigt.
<worksheet/> DocumentFormat.OpenXML.Spreadsheet. Worksheet Eine Blattdefinitionsdatei, welche die Blattdaten enthält.
<sheetData/> DocumentFormat.OpenXML.Spreadsheet.SheetData Die Zellentabelle, die mithilfe von Zeilen gruppiert wird.
<row/> DocumentFormat.OpenXml.Spreadsheet.Row Eine Zeile in der Zellentabelle.
<c/> DocumentFormat.OpenXml.Spreadsheet.Cell Eine Zelle in einer Zeile.
<v/> DocumentFormat.OpenXml.Spreadsheet.CellValue Der Wert einer Zelle.

Funktionsweise des Beispielcodes

Nach dem Öffnen des SpreadsheetDocument Dokuments zur Bearbeitung fügt der Code ein leeres Worksheet Objekt in ein Dokumentpaket ein SpreadsheetDocument . Anschließend fügt ein neues Cell -Objekt in das neue Arbeitsblatt ein und fügt den angegebenen Text in diese Zelle ein.

// Given a document name and text, 
// inserts a new work sheet and writes the text to cell "A1" of the new worksheet.
static void InsertText(string docName, string text)
{
    // Open the document for editing.
    using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
    {
        WorkbookPart workbookPart = spreadSheet.WorkbookPart ?? spreadSheet.AddWorkbookPart();

        // Get the SharedStringTablePart. If it does not exist, create a new one.
        SharedStringTablePart shareStringPart;
        if (workbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)
        {
            shareStringPart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
        }
        else
        {
            shareStringPart = workbookPart.AddNewPart<SharedStringTablePart>();
        }

        // Insert the text into the SharedStringTablePart.
        int index = InsertSharedStringItem(text, shareStringPart);

        // Insert a new worksheet.
        WorksheetPart worksheetPart = InsertWorksheet(workbookPart);

        // Insert cell A1 into the new worksheet.
        Cell cell = InsertCellInWorksheet("A", 1, worksheetPart);

        // Set the value of cell A1.
        cell.CellValue = new CellValue(index.ToString());
        cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
    }
}

Der Code übergibt einen Parameter, der den text darstellt, der in die Zelle eingefügt werden soll, und einen Parameter, der das SharedStringTablePart Objekt für das Arbeitsblatt darstellt. Wenn das ShareStringTablePart Objekt kein -Objekt enthält SharedStringTable , erstellt der Code eines. Wenn der Text bereits im ShareStringTable -Objekt vorhanden ist, gibt der Code den Index für das SharedStringItem Objekt zurück, das den Text darstellt. Andernfalls wird ein neues SharedStringItem -Objekt erstellt, das den Text darstellt.

Der folgende Code überprüft, ob der angegebene Text im SharedStringTablePart -Objekt vorhanden ist, und fügt den Text hinzu, falls er nicht vorhanden ist.

// Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text 
// and inserts it into the SharedStringTablePart. If the item already exists, returns its index.
static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)
{
    // If the part does not contain a SharedStringTable, create one.
    shareStringPart.SharedStringTable ??= new SharedStringTable();

    int i = 0;

    // Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
    foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
    {
        if (item.InnerText == text)
        {
            return i;
        }

        i++;
    }

    // The text does not exist in the part. Create the SharedStringItem and return its index.
    shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));

    return i;
}

Der Code fügt dem -Objekt mithilfe der WorkbookPartAddNewPart -Methode ein neues WorksheetPart -Objekt hinzu. Anschließend wird dem WorksheetPart -Objekt ein neues Worksheet -Objekt hinzugefügt und eine eindeutige ID für das neue Arbeitsblatt abgerufen, indem das maximal SheetId im Tabellenkalkulationsdokument verwendete Objekt ausgewählt und eins hinzugefügt wird, um die neue Blatt-ID zu erstellen. Das Arbeitsblatt erhält einen Namen, indem das Wort "Sheet" mit der Blatt-ID verkettet wird. Anschließend wird das neue Sheet -Objekt an die Sheets Auflistung angefügt.

Der folgende Code fügt ein neues -Objekt ein, Worksheet indem dem -Objekt ein neues WorksheetPart -Objekt WorkbookPart hinzugefügt wird.

// Given a WorkbookPart, inserts a new worksheet.
static WorksheetPart InsertWorksheet(WorkbookPart workbookPart)
{
    // Add a new worksheet part to the workbook.
    WorksheetPart newWorksheetPart = workbookPart.AddNewPart<WorksheetPart>();
    newWorksheetPart.Worksheet = new Worksheet(new SheetData());

    Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>() ?? workbookPart.Workbook.AppendChild(new Sheets());
    string relationshipId = workbookPart.GetIdOfPart(newWorksheetPart);

    // Get a unique ID for the new sheet.
    uint sheetId = 1;
    if (sheets.Elements<Sheet>().Count() > 0)
    {
        sheetId = sheets.Elements<Sheet>().Select<Sheet, uint>(s =>
        {
            if (s.SheetId is not null && s.SheetId.HasValue)
            {
                return s.SheetId.Value;
            }

            return 0;
        }).Max() + 1;
    }

    string sheetName = "Sheet" + sheetId;

    // Append the new worksheet and associate it with the workbook.
    Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
    sheets.Append(sheet);

    return newWorksheetPart;
}

Zum Einfügen einer Zelle in ein Arbeitsblatt bestimmt der Code die Stelle, an der die neue Zelle in die Spalte eingefügt werden soll. Hierzu werden die Zeilenelemente durchlaufen, um die Zelle zu finden, die in sequenzieller Reihenfolge direkt auf die angegebene Zeile folgt. Diese Zeile wird in der refCell Variablen gespeichert. Anschließend wird die neue Zelle vor der Zelle eingefügt, auf die mithilfe der InsertBefore -Methode verwiesen wirdrefCell.

Fügen Sie im folgenden Code ein neues Cell -Objekt in ein -Objekt ein Worksheet .

// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. 
// If the cell already exists, returns it. 
static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
    Worksheet worksheet = worksheetPart.Worksheet;
    SheetData? sheetData = worksheet.GetFirstChild<SheetData>();
    string cellReference = columnName + rowIndex;

    // If the worksheet does not contain a row with the specified row index, insert one.
    Row row;

    if (sheetData?.Elements<Row>().Where(r => r.RowIndex is not null && r.RowIndex == rowIndex).Count() != 0)
    {
        row = sheetData!.Elements<Row>().Where(r => r.RowIndex is not null && r.RowIndex == rowIndex).First();
    }
    else
    {
        row = new Row() { RowIndex = rowIndex };
        sheetData.Append(row);
    }

    // If there is not a cell with the specified column name, insert one.  
    if (row.Elements<Cell>().Where(c => c.CellReference is not null && c.CellReference.Value == columnName + rowIndex).Count() > 0)
    {
        return row.Elements<Cell>().Where(c => c.CellReference is not null && c.CellReference.Value == cellReference).First();
    }
    else
    {
        // Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
        Cell? refCell = null;

        foreach (Cell cell in row.Elements<Cell>())
        {
            if (string.Compare(cell.CellReference?.Value, cellReference, true) > 0)
            {
                refCell = cell;
                break;
            }
        }

        Cell newCell = new Cell() { CellReference = cellReference };
        row.InsertBefore(newCell, refCell);

        return newCell;
    }
}

Beispielcode

Es folgt der vollständige Beispielcode in C# und Visual Basic.

static void InsertText(string docName, string text)
{
    // Open the document for editing.
    using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
    {
        WorkbookPart workbookPart = spreadSheet.WorkbookPart ?? spreadSheet.AddWorkbookPart();

        // Get the SharedStringTablePart. If it does not exist, create a new one.
        SharedStringTablePart shareStringPart;
        if (workbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)
        {
            shareStringPart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
        }
        else
        {
            shareStringPart = workbookPart.AddNewPart<SharedStringTablePart>();
        }

        // Insert the text into the SharedStringTablePart.
        int index = InsertSharedStringItem(text, shareStringPart);

        // Insert a new worksheet.
        WorksheetPart worksheetPart = InsertWorksheet(workbookPart);

        // Insert cell A1 into the new worksheet.
        Cell cell = InsertCellInWorksheet("A", 1, worksheetPart);

        // Set the value of cell A1.
        cell.CellValue = new CellValue(index.ToString());
        cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
    }
}

// Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text 
// and inserts it into the SharedStringTablePart. If the item already exists, returns its index.
static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)
{
    // If the part does not contain a SharedStringTable, create one.
    shareStringPart.SharedStringTable ??= new SharedStringTable();

    int i = 0;

    // Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
    foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
    {
        if (item.InnerText == text)
        {
            return i;
        }

        i++;
    }

    // The text does not exist in the part. Create the SharedStringItem and return its index.
    shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));

    return i;
}

// Given a WorkbookPart, inserts a new worksheet.
static WorksheetPart InsertWorksheet(WorkbookPart workbookPart)
{
    // Add a new worksheet part to the workbook.
    WorksheetPart newWorksheetPart = workbookPart.AddNewPart<WorksheetPart>();
    newWorksheetPart.Worksheet = new Worksheet(new SheetData());

    Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>() ?? workbookPart.Workbook.AppendChild(new Sheets());
    string relationshipId = workbookPart.GetIdOfPart(newWorksheetPart);

    // Get a unique ID for the new sheet.
    uint sheetId = 1;
    if (sheets.Elements<Sheet>().Count() > 0)
    {
        sheetId = sheets.Elements<Sheet>().Select<Sheet, uint>(s =>
        {
            if (s.SheetId is not null && s.SheetId.HasValue)
            {
                return s.SheetId.Value;
            }

            return 0;
        }).Max() + 1;
    }

    string sheetName = "Sheet" + sheetId;

    // Append the new worksheet and associate it with the workbook.
    Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
    sheets.Append(sheet);

    return newWorksheetPart;
}


// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. 
// If the cell already exists, returns it. 
static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
    Worksheet worksheet = worksheetPart.Worksheet;
    SheetData? sheetData = worksheet.GetFirstChild<SheetData>();
    string cellReference = columnName + rowIndex;

    // If the worksheet does not contain a row with the specified row index, insert one.
    Row row;

    if (sheetData?.Elements<Row>().Where(r => r.RowIndex is not null && r.RowIndex == rowIndex).Count() != 0)
    {
        row = sheetData!.Elements<Row>().Where(r => r.RowIndex is not null && r.RowIndex == rowIndex).First();
    }
    else
    {
        row = new Row() { RowIndex = rowIndex };
        sheetData.Append(row);
    }

    // If there is not a cell with the specified column name, insert one.  
    if (row.Elements<Cell>().Where(c => c.CellReference is not null && c.CellReference.Value == columnName + rowIndex).Count() > 0)
    {
        return row.Elements<Cell>().Where(c => c.CellReference is not null && c.CellReference.Value == cellReference).First();
    }
    else
    {
        // Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
        Cell? refCell = null;

        foreach (Cell cell in row.Elements<Cell>())
        {
            if (string.Compare(cell.CellReference?.Value, cellReference, true) > 0)
            {
                refCell = cell;
                break;
            }
        }

        Cell newCell = new Cell() { CellReference = cellReference };
        row.InsertBefore(newCell, refCell);

        return newCell;
    }
}

Siehe auch

Referenz zur Open XML SDK-Klassenbibliothek