gpt4 book ai didi

c# - OpenXML Excel 如何在 SharedStringTable 中更改单元格的值

转载 作者:太空宇宙 更新时间:2023-11-03 23:26:13 27 4
gpt4 key购买 nike

我正在寻找一种安全有效的方法来更新文本可能位于 SharedStringTable 中的单元格的值(这似乎是 MS Excel 创建的任何电子表格的情况)。

顾名思义,SharedStringTable 包含可在多个单元格中使用的字符串。

因此,仅在字符串表中查找项目并更新值并不是可行的方法,因为它也可能被其他单元格使用。

据我所知,必须执行以下操作:

  1. 检查单元格是否使用字符串表

  2. 如果是这样,检查新字符串是否已经存在,在这种情况下就使用它(如果旧字符串不再被任何其他单元格使用,请记住删除它!)

  3. 如果不是,请检查具有旧字符串的项目是否被电子表格中的任何其他单元格引用

  4. 如果是,用新字符串创建新项并引用它

  5. 如果不是,则用新字符串更新现有项目

使用 OpenXML SDK 是否有更简单的解决方案?

还要考虑到,人们可能不仅要更新一个单元格,还要为多个单元格设置新的(不同的)值。所以我们可能会在循环中调用更新单元格方法......

最佳答案

首先接受这个。似乎适用于我的特殊情况。但必须有可能改进,甚至更好,完全不同:

private static void UpdateCell(SharedStringTable sharedStringTable, 
Dictionary<string, SheetData> sheetDatas, string sheetName,
string cellReference, string text)
{
Cell cell = sheetDatas[sheetName].Descendants<Cell>()
.FirstOrDefault(c => c.CellReference.Value == cellReference);
if (cell == null) return;
if (cell.DataType == null || cell.DataType != CellValues.SharedString)
{
cell.RemoveAllChildren();
cell.AppendChild(new InlineString(new Text { Text = text }));
cell.DataType = CellValues.InlineString;
return;
}
// Cell is refering to string table. Check if new text is already in string table, if so use it.
IEnumerable<SharedStringItem> sharedStringItems
= sharedStringTable.Elements<SharedStringItem>();
int i = 0;
foreach (SharedStringItem sharedStringItem in sharedStringItems)
{
if (sharedStringItem.InnerText == text)
{
cell.CellValue = new CellValue(i.ToString());
// TODO: Should clean up, ie remove item with old text from string table if it is no longer in use.
return;
}
i++;
}
// New text not in string table. Check if any other cells in the Workbook referes to item with old text.
foreach (SheetData sheetData in sheetDatas.Values)
{
var cells = sheetData.Descendants<Cell>();
foreach (Cell cell0 in cells)
{
if (cell0.Equals(cell)) continue;
if (cell0.DataType != null
&& cell0.DataType == CellValues.SharedString
&& cell0.CellValue.InnerText == cell.CellValue.InnerText)
{
// Other cells refer to item with old text so we cannot update it. Add new item.
sharedStringTable.AppendChild(new SharedStringItem(new Text(text)));
cell.CellValue.Text = (i).ToString();
return;
}
}
}
// No other cells refered to old item. Update it.
sharedStringItems.ElementAt(int.Parse(cell.CellValue.InnerText)).Text = new Text(text);
}

....

private static void DoIt(string filePath)
{
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(filePath, true))
{
SharedStringTable sharedStringTable
= spreadSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>()
.First().SharedStringTable;
Dictionary<string, SheetData> sheetDatas = new Dictionary<string, SheetData>();
foreach (var sheet in spreadSheet.WorkbookPart.Workbook.Descendants<Sheet>())
{
SheetData sheetData
= (spreadSheet.WorkbookPart.GetPartById(sheet.Id) as WorksheetPart)
.Worksheet.GetFirstChild<SheetData>();
sheetDatas.Add(sheet.Name, sheetData);
}
UpdateCell(sharedStringTable, sheetDatas, "Sheet1", "A2", "Mjau");
}
}

警告:不要按原样使用上面的内容,它适用于特定的电子表格。如果在其他情况下使用它,很可能没有处理。这是我第一次尝试将 OpenXML 用于电子表格。最终遵循了 George Polevoy 提出的建议。更容易并且似乎没有不良副作用(也就是说,在处理可能在您无法控制的情况下编辑的电子表格时,还有一百万个其他问题需要处理...)

关于c# - OpenXML Excel 如何在 SharedStringTable 中更改单元格的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33719193/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com