如何在OpenXml SDK SpreadsheetDocument表中的行之前插入?

时间:2013-04-29 12:05:10

标签: c# openxml-sdk

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

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(); 

}

我的Excel报告模板:

enter image description here

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

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

你不会喜欢这个...问题是你的模板中有第9行和第11行。您必须正确设置它们,因为它们的RowIndex必须更新,并且Row元素的子Cell元素必须具有其CellReference属性(如果有的话,还有CellFormula)。

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

另请注意,我已将起始索引从9更改为8.这是因为代码在执行InsertAfter()之前首先递增(newRowIndex ++)。哦,你会搞清楚......

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

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();
}

答案 1 :(得分:1)

好的!!!,谢谢大家,我在EPPlus

中成功回答了这个问题

例如:

  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();
        } 

答案 2 :(得分:0)

您也可以使用OpenXML SDK,但是在插入之前,您应该手动向下移动插入行下面的所有行。

有用的示例herehere

但是在EPPlus中,它不那么复杂,而且代码更少