открыть XML Excel Вставьте фактическое значение в заполнитель - PullRequest
4 голосов
/ 09 мая 2011

У меня есть ячейка, которая содержит заполнитель «$$ value» в листе Excel, дело в том, что мне нужно заменить фактическое значение заполнителя с помощью 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 ]

4 голосов
/ 09 мая 2011

по умолчанию 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);
    }
}
0 голосов
/ 07 декабря 2017

Решение

 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
        }
...