我正在用 openxml 用 c# 编写一个程序,需要将数据逐个单元格写入 Excel 文件。然而,每当我写入超过 40 列(无论行数多少)时,先前写入同一行的数据就会被删除。 因此,如果我的文件中有 140 列,并且我尝试只写入前 40 列,它会正确执行,如果我希望它写入全部,我最终会得到前 100 列为空,最后 40 列正确填充的结果。 你能弄清楚为什么会出现这个问题吗?我附上受影响的代码部分:
for (int i = 0; i < tempName.Length; i++)
{
if (columnsExcel[Columnindex].ToLower() == tempName[i].ToLower())
{
int index = InsertTextExcel.InsertSharedStringItem(tempValue[i].ToString(), ShareStringPart);
Cell cell = InsertTextExcel.InsertCellInWorksheet(convertlettertonumber(Columnindex + 2), (uint)rowindex, theWorksheet);
// Set cell value
cell.CellValue = new CellValue(index.ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
theWorksheet.Save();
}
}
tempvalue 和 tempname 是字符串数组,sharestringpart 定义为:
SharedStringTablePart shareStringPart = doc.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First()
我已经尝试过用逐行、逐列的方式书写,但结果是完全一样的。
由于您没有显示所有代码(即 Columnindex 和 rowIndex 来自哪里?),我不能完全确定问题是什么,但我有一种预感:行和单元格必须位于xml 中的顺序正确,否则 Excel 将忽略它们。您甚至应该在 Excel 中收到一条错误消息,指出工作簿已损坏,可以通过删除有问题的元素来修复它。
您的函数 InsertCellInWorksheet 只是在末尾附加行。如果你不按顺序调用它,这将不起作用 - 在这种情况下,必须将行插入到正确的位置。细胞也是如此。
下面的代码在正确的位置插入单元格和行。看看是否能解决您的问题。
private DocumentFormat.OpenXml.Spreadsheet.Cell InsertCell(CellAddress address, WorksheetPart OXLWorksheetPart)
{
DocumentFormat.OpenXml.Spreadsheet.Row row = GetRowByIndex((uint)address.RowIndex, OXLWorksheetPart);
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell() { CellReference = address.ToString() };
// same logic as with rows...find the correct position to insert the cell.
DocumentFormat.OpenXml.Spreadsheet.Cell insertBeforeCell = row.Elements<DocumentFormat.OpenXml.Spreadsheet.Cell>().FirstOrDefault(c => c.CellReference.Value.Length == cell.CellReference.Value.Length && c.CellReference > cell.CellReference);
if (insertBeforeCell != null)
{
row.InsertBefore(cell, insertBeforeCell);
}
else
{
row.Append(cell);
}
return cell;
}
private DocumentFormat.OpenXml.Spreadsheet.Row GetRowByIndex(uint rowIndex, WorksheetPart OXLWorksheetPart)
{
SheetData sheetData = OXLWorksheetPart.Worksheet.GetFirstChild<SheetData>();
// Check if the worksheet contains a row with the specified row index.
DocumentFormat.OpenXml.Spreadsheet.Row row = sheetData.Elements<DocumentFormat.OpenXml.Spreadsheet.Row>().FirstOrDefault(r => r.RowIndex == rowIndex);
if (row == null)
{
// the row does not exist yet. Since we have to insert the new row at the correct position, find the first row with the index > the index we want to insert
// and then insert before that row.
row = new DocumentFormat.OpenXml.Spreadsheet.Row() { RowIndex = rowIndex };
DocumentFormat.OpenXml.Spreadsheet.Row insertBeforeRow = sheetData.Elements<DocumentFormat.OpenXml.Spreadsheet.Row>().FirstOrDefault(r => r.RowIndex > rowIndex);
if (insertBeforeRow != null)
{
sheetData.InsertBefore(row, insertBeforeRow);
}
else
{
sheetData.Append(row);
}
}
return row;
}
public class CellAddress
{
public int ColumnIndex { get; set; }
public string ColumnName { get; set;}
public int RowIndex { get; set;}
public override string ToString() => $"{ColumnName}{RowIndex}";
}