Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel openxml-插入一行,移动其他行_Excel_Insert_Row_Openxml - Fatal编程技术网

Excel openxml-插入一行,移动其他行

Excel openxml-插入一行,移动其他行,excel,insert,row,openxml,Excel,Insert,Row,Openxml,我正在使用openxml创建excel报告。openxml使用命名范围对模板excel文件进行操作 客户端要求在行列表的末尾有一个totals行。听起来是个合理的要求 但是,我从db返回的数据表可以包含任意数量的行。使用模板行和“InsertBeforeSelf”,我的总计行被覆盖 我的问题是,使用openxml,如何将行插入到电子表格中,使总计行在每次插入行时下移 关于…假设您使用的是SDK 2.0,我使用此函数做了类似的事情: private static Row CreateRow(Row

我正在使用openxml创建excel报告。openxml使用命名范围对模板excel文件进行操作

客户端要求在行列表的末尾有一个totals行。听起来是个合理的要求

但是,我从db返回的数据表可以包含任意数量的行。使用模板行和“InsertBeforeSelf”,我的总计行被覆盖

我的问题是,使用openxml,如何将行插入到电子表格中,使总计行在每次插入行时下移


关于…

假设您使用的是SDK 2.0,我使用此函数做了类似的事情:

private static Row CreateRow(Row refRow, SheetData sheetData)
    {
        uint rowIndex = refRow.RowIndex.Value;
        uint newRowIndex;
        var newRow = (Row)refRow.Clone();

        /*IEnumerable<Row> rows = sheetData.Descendants<Row>().Where(r => r.RowIndex.Value >= rowIndex);
        foreach (Row row in rows)
        {
            newRowIndex = System.Convert.ToUInt32(row.RowIndex.Value + 1);

            foreach (Cell cell in row.Elements<Cell>())
            {
                string cellReference = cell.CellReference.Value;
                cell.CellReference = new StringValue(cellReference.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString()));
            }

            row.RowIndex = new UInt32Value(newRowIndex);
        }*/

        sheetData.InsertBefore(newRow, refRow);
        return newRow;
    }
private static Row CreateRow(Row refRow,SheetData SheetData)
{
uint rowIndex=refRow.rowIndex.Value;
uint-newRowIndex;
var newRow=(Row)refRow.Clone();
/*IEnumerable rows=sheetData.subjects()。其中(r=>r.RowIndex.Value>=RowIndex);
foreach(行中的行)
{
newRowIndex=System.Convert.ToUInt32(row.RowIndex.Value+1);
foreach(row.Elements()中的单元格)
{
字符串cellReference=cell.cellReference.Value;
cell.CellReference=newStringValue(CellReference.Replace(row.RowIndex.Value.ToString(),newRowIndex.ToString());
}
row.RowIndex=新的uint32值(newRowIndex);
}*/
sheetData.InsertBefore(newRow,refRow);
返回新行;
}
我不确定你以前是如何使用InsertBeforeSelf的,所以也许这并不是一个很大的改进,但这对我来说很有效。我在想你可以把总计行作为参考行。(注释掉的部分是针对您想要维护的引用行之后是否有行。我做了一些修改,但主要来自以下线程:)


因为它返回新行,所以您可以使用该对象,然后使用数据库中的数据编辑单元格值。我希望这至少对任何试图这样做的人有所帮助…

[如果有人有更多的观点,请将此文本作为对M\R\H答案的评论。]

M_R__H给出的解决方案帮助了我,但给这个问题引入了一个新的bug。如果按原样使用给定的CreateRow方法,如果正在移动/重新引用的任何行具有公式,则CalcChain.xml(在包中)将被破坏。 我向建议的CreateRow解决方案添加了以下代码。它仍然不能解决问题,因为,我认为这段代码只是修复了当前正在复制的行引用:

if (cell.CellFormula != null) {
     string cellFormula = cell.CellFormula.Text;
     cell.CellFormula = new CellFormula(cellFormula.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString()));
}
修复/更新CalcChain.xml的正确方法是什么

备注:工作表数据可通过以下方式从工作表中获取:

worksheet.GetFirstChild<SheetData>();
worksheet.GetFirstChild();

必须循环插入行下的所有行和单元格,更改其行索引和单元格引用。我猜OpenXml并不是很聪明,它可以帮助您自动更改索引

static void InsertRow(string sheetName, WorkbookPart wbPart, uint rowIndex)
    {
        Sheet sheet = wbPart.Workbook.Descendants<Sheet>().Where((s) => s.Name == sheetName).FirstOrDefault();

        if (sheet != null)
        {
            Worksheet ws = ((WorksheetPart)(wbPart.GetPartById(sheet.Id))).Worksheet;
            SheetData sheetData = ws.WorksheetPart.Worksheet.GetFirstChild<SheetData>();
            Row refRow = GetRow(sheetData, rowIndex);
            ++rowIndex;

            Cell cell1 = new Cell() { CellReference = "A" + rowIndex };
            CellValue cellValue1 = new CellValue();
            cellValue1.Text = "";
            cell1.Append(cellValue1);
            Row newRow = new Row()
            {
                RowIndex = rowIndex
            };
            newRow.Append(cell1);
            for (int i = (int)rowIndex; i <= sheetData.Elements<Row>().Count(); i++)
            {
                var row = sheetData.Elements<Row>().Where(r => r.RowIndex.Value == i).FirstOrDefault();
                row.RowIndex++;
                foreach (Cell c in row.Elements<Cell>())
                {
                    string refer = c.CellReference.Value;
                    int num = Convert.ToInt32(Regex.Replace(refer, @"[^\d]*", ""));
                    num++;
                    string letters = Regex.Replace(refer, @"[^A-Z]*", "");
                    c.CellReference.Value = letters + num;
                }
            }
            sheetData.InsertAfter(newRow, refRow);
            //ws.Save();
        }
    }

    static Row GetRow(SheetData wsData, UInt32 rowIndex)
    {
        var row = wsData.Elements<Row>().
        Where(r => r.RowIndex.Value == rowIndex).FirstOrDefault();
        if (row == null)
        {
            row = new Row();
            row.RowIndex = rowIndex;
            wsData.Append(row);
        }
        return row;
    }
静态void InsertRow(字符串sheetName、WorkbookPart wbPart、uint行索引)
{
Sheet Sheet=wbPart.Workbook.Subjections()。其中((s)=>s.Name==sheetName.FirstOrDefault();
如果(工作表!=null)
{
工作表ws=((工作表部分)(wbPart.GetPartById(sheet.Id)))。工作表;
SheetData SheetData=ws.WorksheetPart.Worksheet.GetFirstChild();
Row refRow=GetRow(sheetData,rowIndex);
++行索引;
Cell cell1=新单元格(){CellReference=“A”+rowIndex};
CellValue cellValue1=新的CellValue();
cellValue1.Text=“”;
cell1.Append(cellValue1);
行newRow=新行()
{
行索引=行索引
};
newRow.Append(cell1);
for(int i=(int)rowIndex;i r.rowIndex.Value==i.FirstOrDefault();
row.RowIndex++;
foreach(行.Elements()中的单元格c)
{
字符串reference=c.CellReference.Value;
int num=Convert.ToInt32(Regex.Replace(请参阅@“[^\d]*”,”);
num++;
字符串字母=Regex.Replace(请参阅“[^A-Z]*”,”);
c、 CellReference.Value=字母+数字;
}
}
sheetData.InsertAfter(新行,再行);
//ws.Save();
}
}
静态行GetRow(SheetData wsData,UInt32行索引)
{
var row=wsData.Elements()。
其中(r=>r.RowIndex.Value==RowIndex).FirstOrDefault();
if(行==null)
{
行=新行();
row.RowIndex=RowIndex;
wsData.Append(行);
}
返回行;
}

以上解决方案来自:。有一个清晰的解释可能对您有很大帮助。

请注意,合并单元格保存在单独的对象中。如果要保持正确的合并格式,应更新其引用。请查收