使用Open Xml向现有Excel 2007工作簿添加列

本文关键字:2007 工作簿 添加 Excel Open Xml 使用 | 更新日期: 2023-09-27 18:06:34

我有一个预定义的Excel工作簿,所有的工作表在适当的地方,我需要写内容到它。我成功地给细胞写信。

问题是在一个特定的工作表,我需要添加三列到它。在下面的代码中,首先我抓住Worksheet,然后我继续添加列。这段代码运行得很好,我的意思是,没有抛出异常,但是当我试图打开Excel文件时,我得到一个错误,说明有一些内容无法读取,并且此特定工作表的所有内容都被清除。

我知道问题在于此操作,因为如果我注释掉那些添加列的行,工作簿将与我从代码中编写的所有单元格值一起打开。

这是相关的代码,为了测试的目的,我试图添加3列:

using (SpreadsheetDocument document = SpreadsheetDocument.Open(outputPath, true)){
        Sheet sheet2 = document.WorkbookPart.Workbook.Descendants<Sheet>().Single( s => s.Name == "Miscellaneous Credit" );
        Worksheet workSheet2 = ( (WorksheetPart)document.WorkbookPart.GetPartById( sheet2.Id ) ).Worksheet;
        Columns cs = new Columns();
        for ( var y = 1; y <= 3; y++ ) {                    
            Column c = new Column()
            {
                Min = (UInt32Value)1U,
                Max = (UInt32Value)1U,
                Width = 44.33203125D,
                CustomWidth = true
            };
            cs.Append( c );
        }
        workSheet2.Append( cs );
    }

编辑:根据Chris对列概念的解释

using (SpreadsheetDocument document = SpreadsheetDocument.Open(outputPath, true)){
        Sheet sheet2 = document.WorkbookPart.Workbook.Descendants<Sheet>().Single( s => s.Name == "Miscellaneous Credit" );
        Worksheet workSheet2 = ( (WorksheetPart)document.WorkbookPart.GetPartById( sheet2.Id ) ).Worksheet;
       // Check if the column collection exists
            Columns cs = workSheet2.Elements<Columns>().FirstOrDefault();
            if ( ( cs == null ) ) {
                // If Columns appended to worksheet after sheetdata Excel will throw an error.
                SheetData sd = workSheet2.Elements<SheetData>().FirstOrDefault();
                if ( ( sd != null ) ) {
                    cs = workSheet2.InsertBefore( new Columns(), sd );
                }
                else {
                    cs = new Columns();
                    workSheet2.Append( cs );
                }
            }
            //create a column object to define the width of columns 1 to 3  
            Column c = new Column
            {
                Min = (UInt32Value)1U,
                Max = (UInt32Value)3U,
                Width = 44.33203125,
                CustomWidth = true
            };
            cs.Append( c );
    }

使用Open Xml向现有Excel 2007工作簿添加列

回答的第一部分涉及如何设置列的宽度(基于最初的示例代码,我认为您只想定义列的宽度)。

  • 首先,您似乎误解了Column对象的最小和最大属性。它们分别表示受此"列信息"记录影响的第一列和最后列。因此,如果您有一组具有相同宽度的连续列,则可以使用一个Column类设置该宽度。在代码片段中,您定义了相同列(索引1)宽度的3倍。

  • 那么,您假定Columns收集还不存在…

  • 最后,重点是如果Columns集合附加在SheetData之后,Excel将抛出错误

为我工作的最终代码(Open XML SDK 2.0)

using (SpreadsheetDocument document = SpreadsheetDocument.Open(outputPath, true)) {
    Sheet sheet2 = document.WorkbookPart.Workbook.Descendants<Sheet>().Single(s => s.Name == "Your sheet name");
    Worksheet workSheet2 = ((WorksheetPart)document.WorkbookPart.GetPartById(sheet2.Id)).Worksheet;
    // Check if the column collection exists
    Columns cs = workSheet2.Elements<Columns>().FirstOrDefault();
    if ((cs == null)) {
        // If Columns appended to worksheet after sheetdata Excel will throw an error.
        SheetData sd = workSheet2.Elements<SheetData>().FirstOrDefault();
        if ((sd != null)) {
            cs = workSheet2.InsertBefore(new Columns(), sd);
        } else {
            cs = new Columns();
            workSheet2.Append(cs);
        }
    }
    //create a column object to define the width of columns 1 to 3  
    Column c = new Column {
        Min = (UInt32Value)1U,
        Max = (UInt32Value)3U,
        Width = 44.33203125,
        CustomWidth = true
    };
    cs.Append(c);
}

我仍然对如何执行列插入感到困惑。说我有列A B和C,我想在B和C之间插入三列,最终得到A B C D E F列。我怎样才能做到呢?

OpenXml SDK中的Columns对象在这里存储列的样式和宽度信息。在集合中插入Column不会在工作表中"插入"一列。

在OpenXmlSDK中"插入"列是一个非常大而复杂的任务。

从我对问题的理解来看,这意味着你必须找到所有单元格,并通过改变它们的引用来移动它们(例如,在插入3列等之后,带有ref"B1"的单元格将变成"F1")。这意味着您将不得不更改许多其他东西(例如公式中的单元格引用)。

这种任务可以很容易地完成Office。互操作或可能与EEPlusClosedXml等库。