3

这是我在行代码后插入:

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报告模板:

在此处输入图像描述

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

我怎么解决这个问题?

4

3 回答 3

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();
}
于 2013-05-03T10:00:24.243 回答
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();
        } 
于 2013-09-25T11:28:15.703 回答
0

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

这里这里有用的例子。

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

于 2013-09-27T06:17:10.373 回答