Excel openxml-插入一行,移动其他行
我正在使用openxml创建excel报告。openxml使用命名范围对模板excel文件进行操作 客户端要求在行列表的末尾有一个totals行。听起来是个合理的要求 但是,我从db返回的数据表可以包含任意数量的行。使用模板行和“InsertBeforeSelf”,我的总计行被覆盖 我的问题是,使用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
关于…假设您使用的是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(行);
}
返回行;
}
以上解决方案来自:。有一个清晰的解释可能对您有很大帮助。请注意,合并单元格保存在单独的对象中。如果要保持正确的合并格式,应更新其引用。请查收