Open XML SDK 2.0 – 如何更新电子表格中的单元格?

我想使用Open XML SDK 2.0(CT​​P)更新图表使用的电子表格中的单元格。 所有我find的代码示例插入新的单元格。 我正在努力检索正确的工作表。

public static void InsertText(string docName, string text, uint rowIndex, string columnName) { // Open the document for editing. using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true)) { Workbook workBook = spreadSheet.WorkbookPart.Workbook; WorksheetPart worksheetPart = workBook.WorkbookPart. WorksheetParts.First(); SheetData sheetData = worksheetPart.Worksheet. GetFirstChild<SheetData>(); // 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 == rowIndex).Count() != 0) // At this point I am expecting a match for a row that exists // in sheet1 but I am not getting one 

当我在Visual Studio中导航树时,我看到三张表,但没有一个有孩子。 我错过了什么?

这是工作代码。 这是一个原型。 对于更多的更改,可能只打开一次文档。 此外,还有一些硬编码的东西,如工作表名称和单元格types,在可称为生产就绪之前必须进行参数化。 http://openxmldeveloper.org/forums/4005/ShowThread.aspx是非常有帮助的&#x3002;

 using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System.Xml; using System.IO; using System.Diagnostics; namespace OpenXMLWindowsApp { public class OpenXMLWindowsApp { public void UpdateSheet() { UpdateCell("Chart.xlsx", "20", 2, "B"); UpdateCell("Chart.xlsx", "80", 3, "B"); UpdateCell("Chart.xlsx", "80", 2, "C"); UpdateCell("Chart.xlsx", "20", 3, "C"); ProcessStartInfo startInfo = new ProcessStartInfo("Chart.xlsx"); startInfo.WindowStyle = ProcessWindowStyle.Normal; Process.Start(startInfo); } public static void UpdateCell(string docName, string text, uint rowIndex, string columnName) { // Open the document for editing. using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true)) { WorksheetPart worksheetPart = GetWorksheetPartByName(spreadSheet, "Sheet1"); if (worksheetPart != null) { Cell cell = GetCell(worksheetPart.Worksheet, columnName, rowIndex); cell.CellValue = new CellValue(text); cell.DataType = new EnumValue<CellValues>(CellValues.Number); // Save the worksheet. worksheetPart.Worksheet.Save(); } } } private static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName) { IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>(). Elements<Sheet>().Where(s => s.Name == sheetName); if (sheets.Count() == 0) { // The specified worksheet does not exist. return null; } string relationshipId = sheets.First().Id.Value; WorksheetPart worksheetPart = (WorksheetPart) document.WorkbookPart.GetPartById(relationshipId); return worksheetPart; } // Given a worksheet, a column name, and a row index, // gets the cell at the specified column and private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex) { Row row = GetRow(worksheet, rowIndex); if (row == null) return null; return row.Elements<Cell>().Where(c => string.Compare (c.CellReference.Value, columnName + rowIndex, true) == 0).First(); } // Given a worksheet and a row index, return the row. private static Row GetRow(Worksheet worksheet, uint rowIndex) { return worksheet.GetFirstChild<SheetData>(). Elements<Row>().Where(r => r.RowIndex == rowIndex).First(); } } } 

我一直在与Excel的工作,发现这个帮助库是非常有帮助的(我已经创build了自己的帮手字,如果我知道这将节省至less2周): http://simpleooxml.codeplex .COM /

这是更新单元(writer.PasteText(…))所需要的:

 MemoryStream stream = SpreadsheetReader.Create(); SpreadsheetDocument doc = SpreadsheetDocument.Open(stream, true); WorksheetPart worksheetPart = SpreadsheetReader.GetWorksheetPartByName(doc, "Sheet1"); WorksheetWriter writer = new WorksheetWriter(doc, worksheetPart); writer.PasteText("B2", "Hello World"); //Save to the memory stream SpreadsheetWriter.Save(doc); byte[] result = stream.ToArray(); FileStream file = new FileStream(@"D:\x1.xlsx", FileMode.Create); file.Write(result, 0, result.Length); file.Close(); 

@CDonner发布的代码会抛出一些exception,我已经添加了一些代码来处理代码,这会引发exception,这里是

 using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System.Xml; using System.IO; using System.Diagnostics; namespace Application.Model{ public class TempCode { public TempCode() { UpdateCell("E:/Visual Studio Code/Book1.xlsx", "120", 1, "A"); UpdateCell("E:/Visual Studio Code/Book1.xlsx", "220", 2, "B"); UpdateCell("E:/Visual Studio Code/Book1.xlsx", "320", 3, "C"); UpdateCell("E:/Visual Studio Code/Book1.xlsx", "420", 4, "D"); UpdateCell("E:/Visual Studio Code/Book1.xlsx", "520", 5, "E"); ProcessStartInfo startInfo = new ProcessStartInfo("E:/Visual Studio Code/Book1.xlsx"); startInfo.WindowStyle = ProcessWindowStyle.Normal; Process.Start(startInfo); } public static void UpdateCell(string docName, string text,uint rowIndex, string columnName){ // Open the document for editing. using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true)) { WorksheetPart worksheetPart = GetWorksheetPartByName(spreadSheet, "Sheet2"); if (worksheetPart != null) { Cell cell = GetCell(worksheetPart.Worksheet, columnName, rowIndex); cell.CellValue = new CellValue(text); cell.DataType = new EnumValue<CellValues>(CellValues.Number); // Save the worksheet. worksheetPart.Worksheet.Save(); } } } private static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName){ IEnumerable<Sheet> sheets =document.WorkbookPart.Workbook.GetFirstChild<Sheets>(). Elements<Sheet>().Where(s => s.Name == sheetName); if (sheets.Count() == 0){ return null; } string relationshipId = sheets.First().Id.Value; WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId); return worksheetPart; } private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex) { Row row; string cellReference = columnName + rowIndex; if (worksheet.Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0) row = worksheet.GetFirstChild<SheetData>().Elements<Row>().Where(r => r.RowIndex == rowIndex).FirstOrDefault(); else{ row = new Row() { RowIndex = rowIndex }; worksheet.Append(row); } if (row == null) return null; if (row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).Count() > 0) { return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First(); } else{ 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, StyleIndex = (UInt32Value)1U }; row.InsertBefore(newCell, refCell); worksheet.Save(); return newCell; } } } 

}

这是SDK 2.5,但是,这是非常有用的代码在这里find: http : //fczaja.blogspot.dk/2013/05/how-to-read-and-write-excel-cells-with.html

需要稍微修改文本值,将它们添加到SharedStringTablePart

 // 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. private static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart) { // If the part does not contain a SharedStringTable, create one. if (shareStringPart.SharedStringTable == null) { 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 Text(text))); shareStringPart.SharedStringTable.Save(); return i; } 

像这样使用它:

 SharedStringTablePart shareStringPart = GetSharedStringTablePart(excelDoc); // Insert the text into the SharedStringTablePart. int index = InsertSharedStringItem(cellValue, shareStringPart); // Set the value of cell A1. cell.CellValue = new CellValue(index.ToString()); cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);