2011-05-09 34 views
4

我有一個單元格在Excel工作表中包含佔位符「$$ value」,問題是我需要使用Open XML替換佔位符的實際值並將其另存爲單獨的工作簿。open xml excel在佔位符中插入實際值

這是我試過的代碼...它不是取代實際值,也無法保存工作簿。我需要解決這個問題。

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"); 

} 

回答

3

默認情況下,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

嗨ServiceGuy感謝您的回覆......這個問題我從你的代碼面對的我不能保存使用「新的OpenSettings的{自動保存= true}」其獲取參考問題的「OpenSetting」..是否有任何其他方式將工作簿另存爲另一個工作簿,將其作爲模板... – kart 2011-05-09 14:06:09

+0

@ kart:我更新示例代碼喲你的要求(加載模板並保存到新文件)。另外,請確保使用OpenXML SDK 2.0的RTM:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&displaylang=en – mthierba 2011-05-09 15:18:08

+0

@ServiceGuy:謝謝soo多爲您的指導......在調試時,我能夠在DoReplace函數中找到文本替換,但這些替換的文本未顯示在新創建的Excel文件中。對我來說,我無法添加OpenSetting「SpreadsheetDocument.Open(template,true,new OpenSettings {AutoSave = true})」第三個參數不允許在「SpreadsheetDocument.Open()」方法中允許它只允許兩個參數。 .still我不能夠取代新創建的文件中的實際數據..它創建相同的模板文件。 – kart 2011-05-10 09:19:49

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 
     }