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

C# 使用Open Xml向现有Excel 2007工作簿添加列,c#,.net,openxml,openxml-sdk,C#,.net,Openxml,Openxml Sdk,我有一个预定义的Excel工作簿,所有工作表都已准备就绪,我需要将内容写入其中。我成功地给细胞写信 问题在于我需要在特定的工作表中添加三列。在下面的代码中,首先我抓取工作表,然后继续添加列。这段代码运行得很好,我的意思是,没有引发异常,但是当我尝试打开Excel文件时,出现了一个错误,指出有些内容无法读取,并且此特定工作表的所有内容都已清除 我知道问题出在这个操作上,因为如果我注释掉那些添加列的行,工作簿就会打开,而我从代码中写入的所有单元格值都已就位 这是相关代码,出于测试目的,我尝试添加3列

我有一个预定义的Excel工作簿,所有工作表都已准备就绪,我需要将内容写入其中。我成功地给细胞写信

问题在于我需要在特定的工作表中添加三列。在下面的代码中,首先我抓取
工作表
,然后继续添加列。这段代码运行得很好,我的意思是,没有引发异常,但是当我尝试打开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 );
    }
使用(电子表格文档=电子表格文档.Open(outputPath,true)){
sheet2=document.WorkbookPart.Workbook.subjections().Single(s=>s.Name==“杂项信用”);
工作表工作表2=((工作表部分)document.WorkbookPart.GetPartById(sheet2.Id)).Worksheet;
列cs=新列();
对于(变量y=1;y s.名称==“杂项信贷”);
工作表工作表2=((工作表部分)document.WorkbookPart.GetPartById(sheet2.Id)).Worksheet;
//检查列集合是否存在
列cs=工作表2.Elements().FirstOrDefault();
如果((cs==null)){
//如果在sheetdata之后追加到工作表的列,Excel将抛出错误。
SheetData sd=工作表2.Elements().FirstOrDefault();
如果((sd!=null)){
cs=工作表2.InsertBefore(新列(),sd);
}
否则{
cs=新列();
工作表2.附加(cs);
}
}
//创建列对象以定义列1到3的宽度
列c=新列
{
最小值=(UINT32值)1U,
最大值=(UINT32值)3U,
宽度=44.33203125,
CustomWidth=true
};
cs.附加(c);
}
答案的第一部分介绍了如何设置列宽(基于最初的示例代码,我认为您只需要定义列宽)

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

  • 然后,您假定
    集合还不存在

  • 最后,要点是如果
    集合附加在
    SheetData
    之后,Excel将抛出错误
适用于我的最终代码(OpenXMLSDK2.0)

使用(电子表格文档=电子表格文档.Open(outputPath,true)){
Sheet sheet2=document.WorkbookPart.Workbook.subjections().Single(s=>s.Name==“您的工作表名”);
工作表工作表2=((工作表部分)document.WorkbookPart.GetPartById(sheet2.Id)).Worksheet;
//检查列集合是否存在
列cs=工作表2.Elements().FirstOrDefault();
如果((cs==null)){
//如果在sheetdata之后追加到工作表的列,Excel将抛出错误。
SheetData sd=工作表2.Elements().FirstOrDefault();
如果((sd!=null)){
cs=工作表2.InsertBefore(新列(),sd);
}否则{
cs=新列();
工作表2.附加(cs);
}
}
//创建列对象以定义列1到3的宽度
列c=新列{
最小值=(UINT32值)1U,
最大值=(UINT32值)3U,
宽度=44.33203125,
CustomWidth=true
};
cs.附加(c);
}
我仍然不知道如何执行列插入。说我有 A、B和C列,我想在B和C之间插入三列, 以A、B、C、D、E、F列结束。我如何实现它

OpenXMLSDK中的
Columns
对象用于存储列的样式和宽度信息。在集合中插入
不会在工作表中“插入”列

使用OpenXmlSDK,“插入”一个像您所说的那样的列是一项非常庞大而复杂的任务

根据我对问题的理解,这意味着您必须找到所有单元格,并通过更改其引用来移动它们(例如,在插入3列后,引用为“B1”的单元格将变为“F1”,等等…)。这意味着您将不得不更改许多其他内容(例如公式中的单元格引用)


这种任务可以通过Office.Interop或者像EEPlus或ClosedXml这样的库轻松完成

+1。你让我走上了正确的道路。我仍然不知道如何执行列插入。说我有A列、B列和C列,我想在B列和C列之间插入三列,最后是A列、B列、C列、D列、E列和F列。我如何实现它?@Elio.Batista从最初的问题和最初的示例代码中,我想你只想定义列的宽度。但是从你的评论来看,我会说太宽泛了。@Elio.Batista“插入”一个像你所说的那样的专栏对于OpenXmlSDK来说是一个非常大的操作。根据我对问题的理解,这意味着您必须找到所有单元格并更改其引用(例如,在插入3列后,引用为“B1”的单元格将为“F1”)。这意味着您将不得不更改许多其他内容(例如公式中的单元格引用)。这种类型的操作可能是
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 );
    }
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);

}