C# 如何在OpenXml SDK电子表格文档表中插入before行?

C# 如何在OpenXml SDK电子表格文档表中插入before行?,c#,openxml-sdk,C#,Openxml Sdk,这是我在行代码后插入的内容: using (var spreadSheet = SpreadsheetDocument.Open(memoryStream, true, openSettings)) { var worksheet = GetWorksheet(spreadSheet); var worksheetPart = worksheet.WorksheetPart; var sheetData = worksheetPart.Worksheet.GetFir

这是我在行代码后插入的内容:

using (var spreadSheet = SpreadsheetDocument.Open(memoryStream, true, openSettings))
{

    var worksheet = GetWorksheet(spreadSheet);
    var worksheetPart = worksheet.WorksheetPart; 
    var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();

    var newRowIndex = 9;
    foreach (var item in Items)
    {
        newRowIndex++;

        var newRow = new Row()
        {
            RowIndex = (uint)newRowIndex
        };
        var lastRow = sheetData.Elements<Row>().LastOrDefault(l => l.RowIndex == newRowIndex - 1); 

        sheetData.InsertAfter(newRow, lastRow);
    }

    worksheet.Save(); 

}
使用(var电子表格=电子表格文档.Open(memoryStream,true,openSettings))
{
var工作表=获取工作表(电子表格);
var worksheetPart=工作表.worksheetPart;
var sheetData=worksheetPart.Worksheet.GetFirstChild();
var newRowIndex=9;
foreach(项目中的var项目)
{
newRowIndex++;
var newRow=新行()
{
RowIndex=(uint)newRowIndex
};
var lastRow=sheetData.Elements().LastOrDefault(l=>l.RowIndex==newRowIndex-1);
sheetData.InsertAfter(新行、最后一行);
}
工作表。保存();
}
和我的excel报告模板:

此代码工作正常,但结果不正确。问题是新行应该在第9行之前插入


我怎样才能解决这个问题?

你不会喜欢这样的。。。问题是模板中有第9行和第11行。您必须正确设置它们,因为它们的行索引必须更新,行元素的子单元格元素必须更正其CellReference属性(以及CellFormula,如果有)

假设你有6个新项目。然后第9行变成第15行。“旧”行9中的单元格A9必须更新为A15。我已经给出了更新RowIndex和CellReference的代码,但这并不是万无一失的。你已经被警告过了

还要注意,我已经将起始索引从9更改为8。这是因为代码在执行InsertAfter()之前先递增(newRowIndex++)。哦,你会明白的

另外,我会在第9行之前先更新第11行,因为我害怕碰撞。如果您有2个新项目,并且您首先更新了第9行,那么它将成为第11行。然后你有两排11。原来的第11排是哪一排?在这些情况下,当增加行索引时,从具有较高行索引的行开始

using (var spreadSheet = SpreadsheetDocument.Open(memoryStream, true, openSettings))
{

    var worksheet = GetWorksheet(spreadSheet);
    var worksheetPart = worksheet.WorksheetPart;
    var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();

    Row currentRow;
    Row cloneRow;
    Cell currentCell;
    Cell cloneCell;

    // Replace for rows 11 and 9, because they exist after your inserted rows

    currentRow = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex == 11);
    cloneRow = (Row)currentRow.CloneNode(true);
    cloneRow.RowIndex += (uint)Items.Count;
    foreach (var child in cloneRow.ChildElements)
    {
        if (child is Cell)
        {
            currentCell = (Cell)child;
            cloneCell = (Cell)currentCell.CloneNode(true);
            // IMPORTANT! this is a very simplistic way of replace something like
            // A11 to A16 (assuming you have 5 rows to insert)
            // A more robust way of replacing is beyond this solution's scope.
            cloneCell.CellReference = cloneCell.CellReference.Value.Replace("11", cloneRow.RowIndex);
            cloneRow.ReplaceChild<Cell>(cloneCell, currentCell);
        }
    }
    sheetData.ReplaceChild<Row>(cloneRow, currentRow);

    currentRow = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex == 9);
    cloneRow = (Row)currentRow.CloneNode(true);
    cloneRow.RowIndex += (uint)Items.Count;
    foreach (var child in cloneRow.ChildElements)
    {
        if (child is Cell)
        {
            currentCell = (Cell)child;
            cloneCell = (Cell)currentCell.CloneNode(true);
            cloneCell.CellReference = cloneCell.CellReference.Value.Replace("9", cloneRow.RowIndex);
            cloneRow.ReplaceChild<Cell>(cloneCell, currentCell);
        }
    }
    sheetData.ReplaceChild<Row>(cloneRow, currentRow);

    var newRowIndex = 8;
    foreach (var item in Items)
    {
        newRowIndex++;

        var newRow = new Row()
        {
            RowIndex = (uint)newRowIndex
        };
        var lastRow = sheetData.Elements<Row>().LastOrDefault(l => l.RowIndex == newRowIndex - 1);

        sheetData.InsertAfter(newRow, lastRow);
    }

    worksheet.Save();
}
使用(var电子表格=电子表格文档.Open(memoryStream,true,openSettings))
{
var工作表=获取工作表(电子表格);
var worksheetPart=工作表.worksheetPart;
var sheetData=worksheetPart.Worksheet.GetFirstChild();
行当前行;
克罗尼罗街;
细胞电流细胞;
细胞克隆细胞;
//替换第11行和第9行,因为它们位于插入的行之后
currentRow=sheetData.Elements().FirstOrDefault(r=>r.RowIndex==11);
cloneRow=(行)currentRow.CloneNode(真);
cloneRow.RowIndex+=(uint)Items.Count;
foreach(cloneRow.ChildElements中的var child)
{
if(子单元为单元格)
{
currentCell=(单元格)子级;
cloneCell=(单元格)currentCell.CloneNode(true);
//重要!这是一种非常简单的替换方式,例如
//A11到A16(假设有5行要插入)
//一种更健壮的替换方法超出了此解决方案的范围。
cloneCell.CellReference=cloneCell.CellReference.Value.Replace(“11”,cloneRow.RowIndex);
cloneRow.ReplaceChild(cloneCell,currentCell);
}
}
sheetData.ReplaceChild(cloneRow,currentRow);
currentRow=sheetData.Elements().FirstOrDefault(r=>r.RowIndex==9);
cloneRow=(行)currentRow.CloneNode(真);
cloneRow.RowIndex+=(uint)Items.Count;
foreach(cloneRow.ChildElements中的var child)
{
if(子单元为单元格)
{
currentCell=(单元格)子级;
cloneCell=(单元格)currentCell.CloneNode(true);
cloneCell.CellReference=cloneCell.CellReference.Value.Replace(“9”,cloneRow.RowIndex);
cloneRow.ReplaceChild(cloneCell,currentCell);
}
}
sheetData.ReplaceChild(cloneRow,currentRow);
var-newRowIndex=8;
foreach(项目中的var项目)
{
newRowIndex++;
var newRow=新行()
{
RowIndex=(uint)newRowIndex
};
var lastRow=sheetData.Elements().LastOrDefault(l=>l.RowIndex==newRowIndex-1);
sheetData.InsertAfter(新行、最后一行);
}
工作表。保存();
}

好的!!!,谢谢大家,我成功的回答了这个问题

例如:

  public static void AppendRefRow(string path)
    { 
        using (var pck = new ExcelPackage(new FileInfo(path)))
        {

            var ws = pck.Workbook.Worksheets.FirstOrDefault();
            var refRowIndex = 9;
            var refColumnIndex = 1; 

            for (int index = Items.Length - 1; index >= 0; index--)
            {
                ws.InsertRow(refRowIndex, 1, refRowIndex);

                ws.Cells[refRowIndex, refColumnIndex + 0].Value = index + 1;
                //TODO: write here other rows...

            }

            pck.Save();
        } 

您也可以使用OpenXMLSDK实现这一点,但在插入之前,应该手动向下移动插入行下面的所有行

有用的例子和例子


但在EPPlus中,它不那么复杂,代码也更少

检查此链接Veer B.Singh,我插入行没有问题,您的评论有任何问题!!!我的问题是在最后一行之前插入行并更改了最后一行索引…谢谢!未工作,且未移动
工作表中的按钮部分
。并且由于未替换
SheetDate中的
行索引
。是的!,但是简单的lib,它是用WindowsBase&IO包编写OpenXML结构的。