You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:46:02