2014-02-14 15 views
1

我遵循使用的例程here,通過使用.AddPart<>()和一個臨時工作簿作爲中間人,將工作簿中的工作表複製到同一工作簿中,但已經提出了一些的問題。在複製工作表之前,我已對其進行了修改。但是,工作表的複製版本保留原始表單,而不是修改後的表單。下面的代碼:在先前被修改的OpenXML中複製工作表

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

SetupPages()只是獲取其中有一個表,只有一排工作表,然後該行nSections - 1倍,使表nSections行結束副本。這工作。

CopySheet()有以下代碼:

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<>()以執行期望的部分的深層副本,然後再次使用它來深層副本它放回原來的文檔。這樣,所有包含在所需workSheetPart中的引用對象也被複制。

這樣做的工作,就像我現在有我的原始文檔中的工作表副本。但是,調用CopySheet()之前由SetupPages()所做的所有修改都不會出現在複製的工作表中。所以我現在有原始圖紙(在本例中)有11行,複製的圖紙只有1行。

我試圖把和Document.WorkBookPart.WorkBook.Save()之間SetupPages()CopySheet(),看看是否「保存更改」將使其可被複製爲好,但無濟於事。

有沒有我不知道的OpenXML技巧?

編輯:使用調試器我剛剛注意到part.WorkSheet.ChildElements.Count = 15SetupPages後的預期行數)。但是,tempWBP.WorkSheet.ChildElements.Count = 5(在修改SetupPages之前原始表中的行數)。無論出於何種原因,我的程序添加的新行不會被深度複製。現在,我只是不明白。 它應該有事情做了一些不適當的綁定在我的部分或東西行的,下面是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:我已經能夠充分進行復制工作,但它非常不雅觀,並不能解決代碼中的錯誤,而僅僅是假裝沒有問題的緊急措施。我基本上得到了原始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

看看我的解決方案,請 –

回答

1

我已經解決了這個,盡我所能(從我已經從其他論壇聚集我問,最好的「他們」就可以)通過創建副本之前關閉和打開文件。這會使更改永久化,然後在複製時也會複製更改。由此,上述的「黑客」變得不必要了。因此,該代碼的最終版本成爲(與變化,以避免SheetIDSheet.Name衝突):

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); 
} 
相關問題