使用OpenXml(C#)写入指定Excel工作表却全表写入的问题
问题描述
使用C#的OpenXml库向.xlsx文件的指定工作表写入数据时,即便已将SheetData关联到目标工作表,数据仍会出现“写入所有工作表”的异常情况。相关代码如下:
private void WriteToSheet(string sheetName, string filePath) { using var SpreadsheetDocument doc = SpreadsheetDocument.Open(filePath, true); var wbPart = doc.WorkbookPart; if (wbPart == null) return; var sheets = wbPart.Workbook.Descendants<Sheet>(); var sheet = sheets.SingleOrDefault((s) => s.Name.Equals(sheetName)); if (sheet == null) return; var worksheet = ((WorksheetPart)wbPart?.GetPartById(sheet.Id)).Worksheet; var sheetData = worksheet.AppendChild(new SheetData()); WriteTableHeader(sheetData); WriteTableData(sheetData); worksheet.Save(); } private void WriteTableHeader(SheetData sheetData) { var row = sheetData.AppendChild(new Row()); row.Height = 30; row.AppendChild(new Cell() { CellValue = new CellValue("ID"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("File"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Entity"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Form"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Year"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Group"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Line"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Description"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Value 1"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Value 2"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Difference"), DataType = CellValues.String, StyleIndex = 8 }); row.AppendChild(new Cell() { CellValue = new CellValue("Order"), DataType = CellValues.String, StyleIndex = 8 }); }
问题原因
代码中worksheet.AppendChild(new SheetData())的写法存在错误:每个Excel工作表默认已经包含一个SheetData节点,直接新增会导致目标工作表中存在多个SheetData。Excel在解析文件时会将所有SheetData的内容合并显示,造成“数据写入所有工作表”的错觉(实际仅目标工作表被修改,只是重复渲染了多份数据)。
解决方案
修改代码逻辑,优先获取目标工作表中已有的SheetData节点,仅当节点不存在时再创建新的:
private void WriteToSheet(string sheetName, string filePath) { using var SpreadsheetDocument doc = SpreadsheetDocument.Open(filePath, true); var wbPart = doc.WorkbookPart; if (wbPart == null) return; var sheets = wbPart.Workbook.Descendants<Sheet>(); var sheet = sheets.SingleOrDefault((s) => s.Name.Equals(sheetName)); if (sheet == null) return; var worksheetPart = (WorksheetPart)wbPart.GetPartById(sheet.Id); var worksheet = worksheetPart.Worksheet; // 先查找现有SheetData,不存在再创建 var sheetData = worksheet.Descendants<SheetData>().FirstOrDefault(); if (sheetData == null) { sheetData = worksheet.AppendChild(new SheetData()); } WriteTableHeader(sheetData); WriteTableData(sheetData); worksheet.Save(); }
补充说明
- 确保
WriteTableData方法仅操作传入的sheetData对象,避免意外修改其他工作表内容。 - 若需要清空目标工作表原有数据,可在写入新数据前调用
sheetData.RemoveAllChildren<Row>()删除所有行。
内容的提问来源于stack exchange,提问作者Varin
相关产品推荐
相关产品推荐

