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

使用DocumentFormat.OpenXml生成.xlsx文件损坏问题求助

使用DocumentFormat.OpenXml生成Excel时的验证错误问题

我在使用DocumentFormat.OpenXml NuGet包生成Excel文件时遇到问题:调用CloseDocument()后控制台显示数据已写入工作簿,但打开生成的.xlsx文件时,Excel提示工作表存在大量错误需删除。翻了多篇教程和相关帖子,问题依然没解决。

生成Excel的代码

Excel NewExcel = new Excel(FileName);

NewExcel.CreateSheet("Test Sheet");
NewExcel.PrepareColumn(1, 80, true, 55.5);
NewExcel.CreateRow(20.2);
NewExcel.SetCell("Test 1", 1, "A");
NewExcel.SetCell(new DateTime(2010, 7, 14), 1, "B");
NewExcel.FinishSheet();
NewExcel.SaveFile();
NewExcel.CloseDocument();

Excel报错信息

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><logFileName>error133640_01.xml</logFileName><summary>Errors were detected in file 'C:\Users\Frasher Gray\Documents\NsPaintRequest-20240702.xlsx'</summary><removedRecords><removedRecord>Removed Records: Worksheet properties from /xl/workbook.xml part (Workbook)</removedRecord></removedRecords></recoveryLog>

Excel文件生成类代码

public class Excel
{
    public string FileName { get; set; }

    private SpreadsheetDocument ExcelWorkbook;

    private WorksheetPart? CurrentWorksheet;

    private Columns ColumnsInProgress;

    private List<Row> RowsInProgress;

    public Excel(string FileName = "Default File Name")
    {
        this.FileName = FileName;
        ExcelWorkbook = SpreadsheetDocument.Create($"C://Users/Frasher Gray/Documents/{FileName}.xlsx", SpreadsheetDocumentType.Workbook);

        ExcelWorkbook.AddWorkbookPart();
        ExcelWorkbook.WorkbookPart.Workbook = new Workbook();

        ColumnsInProgress = new Columns();
        RowsInProgress = new List<Row>();
    }

    public void PrepareColumn(int FirstColumnAffected, int LastColumnAffected, bool UseCustomWidth = false, double CustomWidth = 0)
    {
        if (UseCustomWidth)
            ColumnsInProgress.Append(new Column() { Min = new UInt32Value((uint)FirstColumnAffected), Max = new UInt32Value((uint)LastColumnAffected), CustomWidth = true, Width = new DoubleValue(CustomWidth) });
        else
            ColumnsInProgress.Append(new Column() { Min = new UInt32Value((uint)FirstColumnAffected), Max = new UInt32Value((uint)LastColumnAffected) });
    }

    public void CreateRow(double? CustomHeight = null)
    {
        SheetData SheetData = CurrentWorksheet.Worksheet.GetFirstChild<SheetData>() ?? CurrentWorksheet.Worksheet.AppendChild(new SheetData());
        Row NewRow = new Row() { RowIndex = new UInt32Value((uint)SheetData.Count() + 1) };
        if (CustomHeight != null)
            NewRow.Height = CustomHeight;
        RowsInProgress.Add(NewRow);
        SheetData.Append(NewRow);
    }

    public void SetCell<T>(T CellValue, int Row, string Column)
    {
        Cell NewCell = new Cell() { CellReference = $"{Column}{Row}" };
        if (CellValue.GetType() == typeof(string))
        {
            NewCell.DataType = new EnumValue<CellValues>(CellValues.String);
            NewCell.CellValue = new CellValue(CellValue.ToString() ?? string.Empty);
        }
        else if (CellValue.GetType() == typeof(DateTime))
        {
            NewCell.DataType = new EnumValue<CellValues>(CellValues.Date);
            NewCell.CellValue = new CellValue(Convert.ToDateTime(CellValue));
        }
        else
        {
            NewCell.DataType = new EnumValue<CellValues>(CellValues.Number);
            NewCell.CellValue = new CellValue(Convert.ToDouble(CellValue));
        }

        if (RowsInProgress[Row - 1].Elements<Cell>().Count() > 0)
        {
            RowsInProgress[Row - 1].InsertAfter(NewCell, RowsInProgress[Row - 1].Elements<Cell>().Last());
        }
        else
        {
            RowsInProgress[Row - 1].AddChild(NewCell);
        }
        CurrentWorksheet.Worksheet.Save();
    }

    public void CreateSheet(string SheetName)
    {
        CurrentWorksheet = ExcelWorkbook.WorkbookPart.AddNewPart<WorksheetPart>();
        CurrentWorksheet.Worksheet = new Worksheet(new SheetData());

        Sheets Sheets = ExcelWorkbook.WorkbookPart.Workbook.GetFirstChild<Sheets>() ?? ExcelWorkbook.WorkbookPart.Workbook.AppendChild(new Sheets());
        uint SheetId = (uint)(Sheets.Elements<Sheet>().Count() + 1);
        Sheet Sheet = new Sheet() { Id = ExcelWorkbook.GetIdOfPart(ExcelWorkbook.WorkbookPart), SheetId = SheetId, Name = SheetName };
        Sheets.Append(Sheet);
    }

    public void FinishSheet()
    {
        CurrentWorksheet.Worksheet.InsertAt(ColumnsInProgress, 0);
        ColumnsInProgress = new Columns();
        RowsInProgress.Clear();
        CurrentWorksheet.Worksheet.Save();
    }

    public void SaveFile()
    {
        ExcelWorkbook.WorkbookPart.Workbook.Save();
    }

    public void CloseDocument()
    {
        foreach (Row R in ExcelWorkbook.WorkbookPart.WorksheetParts.FirstOrDefault().Worksheet.GetFirstChild<SheetData>())
        {
            foreach (Cell P in R.ChildElements)
            {
                Console.WriteLine(P.InnerText + " " + P.CellReference);
            }
        }
        ExcelWorkbook.Dispose();
    }
}

额外验证错误信息

文档存在1个验证错误
描述:属性'http://schemas.openxmlformats.org/officeDocument/2006/relationships:id'引用的关系'R2c7e7002bf544f0d'不存在。
错误类型:语义错误
节点:DocumentFormat.OpenXml.Spreadsheet.Sheet
路径:/x:workbook[1]/x:sheets[1]/x:sheet[1]
部件:/xl/workbook.xml

我试过移除FinishSheet()中的ColumnsInProgress = new Columns();语句,但问题没改善。现在搞不懂这个错误的具体含义,希望能得到帮助。

内容的提问来源于stack exchange,提问作者Frasher Gray

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:29:55