open xml excel在占位符中插入实际值

时间:2011-05-09 08:30:49

标签: 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");

}

2 个答案:

答案 0 :(得分:4)

默认情况下,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);
    }
}

答案 1 :(得分:0)

<强>解决方案

 private static void ProcessTemplate(Stream template, Dictionary<string,string> toReplace)
        {
            using (var workbook = SpreadsheetDocument.Open(template, true, new OpenSettings { AutoSave = true }))
            {

                workbook.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
                workbook.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;

                //Replace  SheetNames
                foreach (Sheet sheet in workbook.WorkbookPart.Workbook.Sheets)
                    foreach (var key in toReplace.Keys)
                        sheet.Name.Value = sheet.Name.Value.Replace(key, toReplace[key]);

                foreach (WorksheetPart wsheetpart in workbook.WorkbookPart.WorksheetParts)
                    foreach (SheetData sheetd in wsheetpart.Worksheet.Descendants<x.SheetData>())
                        foreach (Row r in wsheetpart.Worksheet.Descendants<x.Row>())
                            foreach (Cell c in r.Descendants<x.Cell>())
                                if (c.CellFormula != null)
                                {
                                    foreach (var key in toReplace.Keys)
                                        c.CellFormula.Text = c.CellFormula.Text.Replace(key, toReplace[key]);
                                }

                                // Replace shared strings
                                SharedStringTablePart sharedStringsPart = workbook.WorkbookPart.SharedStringTablePart;

                IEnumerable<x.Text> sharedStringTextElements = sharedStringsPart.SharedStringTable.Descendants<x.Text>();
                for(int i =0;i<toReplace.Keys.Count; i++)
                    DoReplace(sharedStringTextElements, toReplace);

                IEnumerable<x.Formula> sharedStringTextElementsF = sharedStringsPart.SharedStringTable.Descendants<x.Formula>();
                for (int i = 0; i < toReplace.Keys.Count; i++)
                    DoReplaceFormula(sharedStringTextElementsF, toReplace);

                // Replace inline strings
                IEnumerable<WorksheetPart> worksheetParts = workbook.GetPartsOfType<WorksheetPart>();
                foreach (var worksheet in worksheetParts)
                {

                    var allTextElements = worksheet.Worksheet.Descendants<x.Text>();
                    DoReplace(allTextElements, toReplace);

                    var allTextElements2 = worksheet.Worksheet.Descendants<x.Formula>();
                    DoReplaceFormula(allTextElements2, toReplace);

                }

            } // AutoSave enabled
        }