2011-05-09 6 views
4

엑셀 시트에 자리 표시 자 "$$ 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

입니다 다음

(일부 인라인 주석) 샘플 응용 프로그램입니다 can not는 "OpenSettings"에 대한 참조 문제를 가져 오는 "new OpenSettings {AutoSave = true}"를 사용하여 저장할 수 없습니다. 템플릿으로 남겨 놓은 다른 통합 문서로 통합 문서를 저장하는 다른 방법은 없습니다 .... – kart

+0

@ kart : 요를 충족 샘플 코드 ur 요구 사항 (템플릿로드 및 새 파일 저장). 또한 OpenXML SDK 2.0의 RTM을 사용해야합니다. http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&displaylang=en – mthierba

+0

@ServiceGuy : 감사합니다. soo 많은 당신의 의지 ... 디버깅하는 동안 DoReplace 함수에서 텍스트 바꾸기를 찾을 수 있지만 대체 된 텍스트가 새로 만든 Excel 파일에 표시되지 않습니다. 나를 위해 나는 "SpreadsheetDocument.Open (템플릿, 사실, 새로운 OpenSettings {자동 저장 = true})"OpenSetting 추가 할 수 없습니다 "SpreadsheetDocument.Open()"메서드는 두 개의 매개 변수를 허용하는 세 번째 매개 변수를 허용하지 않습니다 .. .still 나는 새로 만든 file..its의 실제 데이터를 템플릿 파일과 동일하게 대체 할 수 없습니다. – kart

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 
     } 
가 답장을 보내 주셔서 감사 ... 문제가 코드에서 직면하고 안녕 ServiceGuy 내가
관련 문제