2014-02-14 3 views
1

here 루틴을 사용하여 통합 문서의 워크 시트를 .AddPart<>()과 임시 워크 북을 사용하여 같은 통합 문서로 복사했지만 중개자 역할을 수행했지만 문제. 워크 시트를 복사하기 전에 수정했습니다. 그러나 워크 시트의 복사 된 버전은 수정 된 원본 시트가 아니라 원본 시트를 유지합니다. 여기 코드는 다음과 같습니다이전에 수정 된 OpenXML의 워크 시트 복사

Document = SpreadsheetDocument.Open(filename, true); 
SetupPages(0, nSections); 
CopySheet(1); 

SetupPages()는 간단히 테이블 nSections 행과 함께 끝나도록, nSections - 1 번 행 사본을 하나 개의 행이있는 테이블이 워크 시트를 얻고. 이 작동합니다.

private void CopySheet(int sNum) 
{ 
    var tempSheet = SpreadsheetDocument.Create(new MemoryStream(), SpreadsheetDocumentType.Workbook); 
    WorkbookPart tempWBP = tempSheet.AddWorkbookPart(); 
    var part = Document.XGetWorkSheetPart(sNum); 
    WorksheetPart tempWSP = tempWBP.AddPart<WorksheetPart>(part); 
    var copy = Document.WorkbookPart.AddPart<WorksheetPart>(tempWSP); 

    var sheets = Document.WorkbookPart.Workbook.GetFirstChild<Sheets>(); 
    var sheet = new Sheet(); 
    sheet.Id = Document.WorkbookPart.GetIdOfPart(copy); 
    sheet.Name = "AAA"; 
    sheet.SheetId = (uint)sheets.ChildElements.Count + 1; 
    sheets.Append(sheet); 
} 

이 방법은 원하는 workSheetPart를 얻고 원하는 부분의 깊은 복사를 수행 할 tempSheet.AddPart<>()을 사용하고 다음 다시 원래의 문서에 딥 카피에 다시 사용

CopySheet() 다음과 같은 코드가 있습니다. 이 방법으로 원하는 workSheetPart에 포함 된 모든 참조 된 객체도 복사됩니다.

원본 문서에 workSheet 사본이있는만큼 작동합니다. 그러나 CopySheet()을 호출하기 전에 SetupPages()의 모든 수정 내용이 복사 된 워크 시트에 나타나지 않습니다. 그래서 이제는 (이 예제에서는) 11 개의 행과 1 개의 행만있는 복사 된 시트가있는 원본 시트를 갖게되었습니다.

SetupPages()CopySheet() 사이에 Document.WorkBookPart.WorkBook.Save()을 넣으려고했는데 "변경 사항 저장"으로 복사해도 사용할 수 있지만 아무런 효과가 없습니다.

내가 모르는 OpenXML 트릭이 있습니까?

편집 : 디버거를 사용하여 part.WorkSheet.ChildElements.Count = 15 (SetupPages 다음에 예상되는 행 수)에 주목했습니다. 그러나 tempWBP.WorkSheet.ChildElements.Count = 5 (수정 전 원래 시트의 행 수는 SetupPages). 어떤 이유로 든 내 프로그램에 추가 된 새로운 행은 완전히 복사되지 않습니다. 이제이 사실을 이해하지 못합니다.

public void SetupPages(int p, int nSections) 
{ 
    Regex rn = new Regex("[0-9]+"); 
    Regex rs = new Regex("[A-Z]+"); 
    SheetData sData = Document.XGet<SheetData>(2 * p + 1); 
    for (uint i = 1; i < nSections; i++) 
    { 
     var r = sData.ChildElements.GetItem(4).Clone() as Row; 
     r.RowIndex.Value += i; 
     foreach (OpenXmlElement _c in r.ChildElements) 
     { 
      var c = _c as Cell; 
      Match mn = rn.Match(c.CellReference.Value); 
      Match ms = rs.Match(c.CellReference.Value); 
      string str = (int.Parse(mn.Value) + i).ToString(); 
      c.CellReference.Value = ms.Value + str; 
     } 
     (r.FirstChild as Cell).CellValue = new CellValue((i + 1).ToString()); 
     sData.Append(r); 
    } 
} 

편집 2 : 이 내 일부 또는 뭔가에 행의 일부 부적절한 바인딩과 함께 할 수있는 뭔가가 있어야, 여기 SetupPages()의 정의의 나는 완전히 복사 작업을 할 수있었습니다가, 그러나 이것은 매우 비현실적이며 명확하게 코드의 오류가 무엇인지를 고치지는 않지만 단지 문제가 없다고 가장하는 비상 조치 만 해결합니다. 기본적으로 원래 SheetData (변경 사항이 포함 된 SetupPages)의 복제본을 가져오고 복사 된 SheetSheetData으로 설정합니다. 저는 정보 목적으로 여기에 게시하고 있습니다 만, 제가 보지 못하는 코드에서 누군가가 여전히 잘못된 점을 지적 할 수 있다면, 나는 꽤 감사 할 것입니다. 누구든지 관심이있는 경우 여기에 CopySheet()의 "해킹 된"버전이 있습니다.

private void CopySheet(int sNum) 
{ 
    var tempSheet = SpreadsheetDocument.Create(new MemoryStream(), SpreadsheetDocumentType.Workbook); 
    WorkbookPart tempWBP = tempSheet.AddWorkbookPart(); 
    var part = Document.XGetWorkSheetPart(sNum); 
    var b = part.Worksheet.ChildElements[5].Clone() as SheetData; 
    WorksheetPart tempWSP = tempWBP.AddPart<WorksheetPart>(part); 

    var copy = Document.WorkbookPart.AddPart<WorksheetPart>(tempWSP); 
    copy.Worksheet.RemoveChild<SheetData>(copy.Worksheet.ChildElements[5] as SheetData); 
    copy.Worksheet.InsertAt<SheetData>(b, 5); 

    var sheets = Document.WorkbookPart.Workbook.GetFirstChild<Sheets>(); 
    var sheet = new Sheet(); 
    sheet.Id = Document.WorkbookPart.GetIdOfPart(copy); 
    sheet.Name = "AAA"; 
    sheet.SheetId = (uint)sheets.ChildElements.Count + 1; 
    sheets.Append(sheet); 
} 
+0

봐주십시오 : 코드의 최종 버전은 그러므로 (SheetIDSheet.Name 충돌을 피하기 위해 변화)이되었다 –

답변

1

나는이 문제를 해결 한 최선을 다해 내가 할 수있는 (그리고 나는 다른 포럼에서 수집 한 내가 질문 한에서, 최고로 "그들이"수) 이전 복사본을 만드는 파일을 닫고 열어 . 이렇게하면 변경 사항이 영구적으로 적용되고 복사되면 변경 사항도 복사됩니다. 이것으로, 위에서 설명한 "해킹"이 불필요하게됩니다.내 솔루션에서

private void CopySheet(int sNum, int pNum, string type) 
{ 
    var tempSheet = SpreadsheetDocument.Create(new MemoryStream(), SpreadsheetDocumentType.Workbook); 
    WorkbookPart tempWBP = tempSheet.AddWorkbookPart(); 
    var part = Document.XGetWorkSheetPart(sNum); 
    WorksheetPart tempWSP = tempWBP.AddPart<WorksheetPart>(part); 
    var copy = Document.WorkbookPart.AddPart<WorksheetPart>(tempWSP); 
    var sheets = Document.WorkbookPart.Workbook.GetFirstChild<Sheets>(); 
    var sheet = new Sheet(); 
    sheet.Id = Document.WorkbookPart.GetIdOfPart(copy); 
    sheet.Name = "Phase " + pNum + " " + type; 
    uint id = 1; 
    bool valid = false; 
    while (!valid) 
    { 
     uint temp = id; 
     foreach (OpenXmlElement e in sheets.ChildElements) 
     { 
      var s = e as Sheet; 
      if (id == s.SheetId.Value) 
      { 
       id++; 
       break; 
      } 
     } 
     if (temp == id) 
      valid = true; 
    } 
    sheet.SheetId = id; 
    sheets.Append(sheet); 
}