kar*_*art 4 c# excel openxml-sdk
我有一个包含 Excel 工作表中占位符“$$value”的单元格,问题是我需要使用 Open XML 替换占位符的实际值并将其保存为单独的工作簿。
这是我尝试过的代码……它没有替换实际值,而且我也无法保存工作簿。我需要解决这个问题。
WorksheetPart worksheetPart = (WorksheetPart)myWorkbook.WorkbookPart.GetPartById(sheet.Id);
DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet = worksheetPart.Worksheet;
string _txt1 = "$$value";
if (_txt1.Contains("$$"))
{
worksheet.InnerText.Replace(_txt1, "test");
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,Excel 将字符串存储在全局中(每个工作簿 1 个)SharedStringTablePart。因此,这是您需要定位的目标。但是,OpenXML 格式还允许在 WorksheetParts 内嵌入文本。因此,一个完整的解决方案也需要在那里寻找。
这是一个示例应用程序(带有一些内嵌注释):
using DocumentFormat.OpenXml.Packaging;
using x = DocumentFormat.OpenXml.Spreadsheet;
class Program
{
private static readonly string placeHolder = "$$value";
static void Main()
{
var templatePath = @"C:\Temp\template.xlsx";
var resultPath = @"C:\Temp\result.xlsx";
string replacementText = "test";
using (Stream xlsxStream = new MemoryStream())
{
// Read template from disk
using (var fileStream = File.OpenRead(templatePath))
fileStream.CopyTo(xlsxStream);
// Do replacements
ProcessTemplate(xlsxStream, replacementText);
// Reset stream to beginning
xlsxStream.Seek(0L, SeekOrigin.Begin);
// Write results back to disk
using (var resultFile = File.Create(resultPath))
xlsxStream.CopyTo(resultFile);
}
}
private static void ProcessTemplate(Stream template, string replacementText)
{
using (var workbook = SpreadsheetDocument.Open(template, true, new OpenSettings { AutoSave = true }))
{
// Replace shared strings
SharedStringTablePart sharedStringsPart = workbook.WorkbookPart.SharedStringTablePart;
IEnumerable<x.Text> sharedStringTextElements = sharedStringsPart.SharedStringTable.Descendants<x.Text>();
DoReplace(sharedStringTextElements, replacementText);
// Replace inline strings
IEnumerable<WorksheetPart> worksheetParts = workbook.GetPartsOfType<WorksheetPart>();
foreach (var worksheet in worksheetParts)
{
var allTextElements = worksheet.Worksheet.Descendants<x.Text>();
DoReplace(allTextElements, replacementText);
}
} // AutoSave enabled
}
private static void DoReplace(IEnumerable<x.Text> textElements, string replacementText)
{
foreach (var text in textElements)
{
if (text.Text.Contains(placeHolder))
text.Text = text.Text.Replace(placeHolder, replacementText);
}
}
Run Code Online (Sandbox Code Playgroud)