2015-07-15 14 views
15

Ich versuche, einige Daten in ein Excel-Blatt S1 zu exportieren, dessen Daten in den nächsten zwei Blättern S2 and S3 als Pivot-Ansichten angezeigt werden. Ich kann einen einzelnen Drehpunkt erstellen und es funktioniert perfekt. Wenn ich jedoch zwei Pivots erstelle, wird die entsprechende Excel-Datei als fehlerhaft gerendert.ClosedXML - Erstellen mehrerer Pivot-Tabellen

durch korrupt Ich meine,

Beim Klicken ja, bekomme ich diese -

Corrupt

Hier ist der Code, den ich die Zapfen erstellen bin mit -

using XL = ClosedXML.Excel; 
... 
XL.XLWorkbook wb = new XL.XLWorkbook(); 
dsData = Session["ExportData"] as DataSet; 

var sheet1 = wb.Worksheets.Add("output table"); 
sheet1.Cell(1, 1).InsertTable(dsData.Tables[0], "output table", true); 

// sheet1 is the reference sheet S1 
var dataRange = sheet1.RangeUsed(); 

// First Pivot 
XL.IXLWorksheet ptSheet1 = wb.Worksheets.Add("S2"); 

var pt1 = ptSheet1.PivotTables.AddNew("PivotTable1", ptSheet.Cell(3, 1), dataRange); 


pt1.ReportFilters.Add("CX"); 

pt1.RowLabels.Add("C1"); 
pt1.RowLabels.Add("C2"); 
pt1.RowLabels.Add("C3"); 
pt1.RowLabels.Add("C4"); 

pt1.ColumnLabels.Add("CL1"); 
pt1.ColumnLabels.Add("CL2"); 
pt1.ColumnLabels.Add("CL3"); 

pt1.Values.Add("V").SummaryFormula = XL.XLPivotSummary.Sum; 


// Second Pivot 
XL.IXLWorksheet ptSheet2 = wb.Worksheets.Add("S3"); 

var pt2 = ptSheet2.PivotTables.AddNew("PivotTable2", ptSheet1.Cell(3, 1), dataRange); 

pt2.ReportFilters.Add("QQ"); 

pt2.RowLabels.Add("C1"); 
pt2.RowLabels.Add("C2"); 

pt2.ColumnLabels.Add("CL1"); 
pt2.ColumnLabels.Add("CL2"); 
pt2.ColumnLabels.Add("CL3"); 

pt2.Values.Add("V").SummaryFormula = XL.XLPivotSummary.Sum; 

C1, C2, C3. C4 and V sind die Spaltennamen in meinem Referenzblatt S1.

+1

was meinst du mit rendert als korrupt? irgendwelche Fehler auftreten? Bitte zeigen Sie uns den ganzen Code für den Export – jomsk1e

+0

@ jomsk1e Ich habe die Frage aktualisiert, bitte überprüfen. –

+1

Ich erlebe das exakt gleiche Problem. . Haben Sie jemals eine Lösung oder einen Workaround gefunden? – leora

Antwort

11

Das Problem wird durch eine ClosedXML Implementierung Fehler verursacht.

Es kann leicht mit dem folgenden Code-Schnipsel (eine modifizierte Version der Pivot-Tabellen Beispiel) und öffnen Sie die resultierende Datei in Excel wiedergegeben werden:

static void CreateTestPivotTables(string filePath) 
{ 
    var wb = new XLWorkbook(); 

    var wsData = wb.Worksheets.Add("Data");    
    wsData.Cell("A1").Value = "Category"; 
    wsData.Cell("A2").Value = "A"; 
    wsData.Cell("A3").Value = "B"; 
    wsData.Cell("A4").Value = "B"; 
    wsData.Cell("B1").Value = "Number"; 
    wsData.Cell("B2").Value = 100; 
    wsData.Cell("B3").Value = 150; 
    wsData.Cell("B4").Value = 75; 
    var source = wsData.Range("A1:B4"); 

    for (int i = 1; i <= 2; i++) 
    { 
     var name = "PT" + i; 
     var wsPT = wb.Worksheets.Add(name); 
     var pt = wsPT.PivotTables.AddNew(name, wsPT.Cell("A1"), source); 
     pt.RowLabels.Add("Category"); 
     pt.Values.Add("Number") 
      .ShowAsPctFrom("Category").And("A") 
      .NumberFormat.Format = "0%"; 
    } 

    wb.SaveAs(filePath); 
} 

Der Fehler in XLWorkbook_Save.cs befindet sich - GeneratePivotTables Methode:

private static void GeneratePivotTables(WorkbookPart workbookPart, WorksheetPart worksheetPart, 
    XLWorksheet xlWorksheet, 
    SaveContext context) 
{ 
    foreach (var pt in xlWorksheet.PivotTables) 
    { 
     var ptCdp = context.RelIdGenerator.GetNext(RelType.Workbook); 

     var pivotTableCacheDefinitionPart = workbookPart.AddNewPart<PivotTableCacheDefinitionPart>(ptCdp); 
     GeneratePivotTableCacheDefinitionPartContent(pivotTableCacheDefinitionPart, pt); 

     var pivotCaches = new PivotCaches(); 
     var pivotCache = new PivotCache {CacheId = 0U, Id = ptCdp}; 

     pivotCaches.AppendChild(pivotCache); 

     workbookPart.Workbook.AppendChild(pivotCaches); 

     var pivotTablePart = 
      worksheetPart.AddNewPart<PivotTablePart>(context.RelIdGenerator.GetNext(RelType.Workbook)); 
     GeneratePivotTablePartContent(pivotTablePart, pt); 

     pivotTablePart.AddPart(pivotTableCacheDefinitionPart, context.RelIdGenerator.GetNext(RelType.Workbook)); 
    } 
} 

durch die Linie workbookPart.Workbook.AppendChild(pivotCaches);, die mehrere PivotCaches zu workbookPart.Workbook fügt hinzu, während es erlaubt ist, enthalten 0 oder 1

Mit diesem wird gesagt, ist der einzige Weg, um es in den Quellcode zu beheben, ist durch das obige Verfahren wie folgt zu ändern:

private static void GeneratePivotTables(WorkbookPart workbookPart, WorksheetPart worksheetPart, 
    XLWorksheet xlWorksheet, 
    SaveContext context) 
{ 
    var pivotCaches = workbookPart.Workbook.GetFirstChild<PivotCaches>(); 
    foreach (var pt in xlWorksheet.PivotTables) 
    { 
     var ptCdp = context.RelIdGenerator.GetNext(RelType.Workbook); 

     var pivotTableCacheDefinitionPart = workbookPart.AddNewPart<PivotTableCacheDefinitionPart>(ptCdp); 
     GeneratePivotTableCacheDefinitionPartContent(pivotTableCacheDefinitionPart, pt); 

     if (pivotCaches == null) 
      workbookPart.Workbook.AppendChild(pivotCaches = new PivotCaches()); 
     var pivotCache = new PivotCache { CacheId = (uint)pivotCaches.Count(), Id = ptCdp }; 
     pivotCaches.AppendChild(pivotCache); 

     var pivotTablePart = 
      worksheetPart.AddNewPart<PivotTablePart>(context.RelIdGenerator.GetNext(RelType.Workbook)); 
     GeneratePivotTablePartContent(pivotTablePart, pt); 
     pivotTablePart.PivotTableDefinition.CacheId = pivotCache.CacheId; 

     pivotTablePart.AddPart(pivotTableCacheDefinitionPart, context.RelIdGenerator.GetNext(RelType.Workbook)); 
    } 
} 

Update: Die gute Nachricht ist, dass meine Post eine ClosedXML source repository fix von Francois Botha ausgelöst (auch Credits zu petelids wer hat es dort heraufgebracht), also können Sie den Code von dort bis zu ihrer nächsten Veröffentlichung nehmen, die hoffentlich es einschließen wird.

+0

Als Betreuer des Pakets würde ich es lieben, wenn Leute Patches als Pull-Requests einreichen könnten. http: // GitHub.com/ClosedXML/ClosedXML –

+0

@FrancoisBotha Sicher, ich habe gerade gestern auf die Fragen gearbeitet und habe keine Zeit für den Beitrag (es hat einige zusätzliche Anforderungen, denke ich, nicht wie nur ein Code-Snippet werfen), und dann scheint der Benutzer petelids das schon gemacht zu haben. –

+1

@IvanStoev - Ich tat, aber ich stürzte es und machte ein bisschen wie ein Hash davon. Ich habe meine Antwort gelöscht, da sie keinen Wert hinzufügte (und stattdessen Ihren Wert hochstufte). FrancoisBotha hat einen besseren Patch erstellt. – petelids

2

Versuchen Sie diese Modifikation. Ich habe eine Notiz gemacht, wo ich eine zusätzliche Zeile hinzugefügt habe. Außerdem denke ich, dass die AddNew() Methode möglicherweise die falsche Arbeitsblattverweis hatte? Möglicherweise haben Sie versucht, eine Pivot-Tabelle über einer anderen hinzuzufügen. Das war vielleicht das eigentliche Problem und nicht die zusätzliche Zeile, die ich hinzugefügt habe.

using XL = ClosedXML.Excel; 
... 
XL.XLWorkbook wb = new XL.XLWorkbook(); 
dsData = Session["ExportData"] as DataSet; 
var sheet1 = wb.Worksheets.Add("output table"); 
sheet1.Cell(1, 1).InsertTable(dsData.Tables[0], "output table", true); 

// sheet1 is the reference sheet S1 
var dataRange = sheet1.RangeUsed(); 
PivotCache cache = wb.PivotCaches.Add(dataRange); //---THIS LINE HAS BEEN ADDED--- 

// First Pivot 
XL.IXLWorksheet ptSheet1 = wb.Worksheets.Add("S2"); 
var pt1 = ptSheet1.PivotTables.AddNew("PivotTable1", ptSheet1.Cell(3, 1), cache); 
//Changed ptSheet.Cell... to ptSheet1.Cell... 
pt1.ReportFilters.Add("CX"); 
pt1.RowLabels.Add("C1"); 
pt1.RowLabels.Add("C2"); 
pt1.RowLabels.Add("C3"); 
pt1.RowLabels.Add("C4"); 
pt1.ColumnLabels.Add("CL1"); 
pt1.ColumnLabels.Add("CL2"); 
pt1.ColumnLabels.Add("CL3"); 
pt1.Values.Add("V").SummaryFormula = XL.XLPivotSummary.Sum; 

// Second Pivot 
XL.IXLWorksheet ptSheet2 = wb.Worksheets.Add("S3"); 
var pt2 = ptSheet2.PivotTables.AddNew("PivotTable2", ptSheet2.Cell(3, 1), cache); 
//Changed ptSheet1.Cell... to ptSheet2.Cell... 
pt2.ReportFilters.Add("QQ"); 
pt2.RowLabels.Add("C1"); 
pt2.RowLabels.Add("C2"); 
pt2.ColumnLabels.Add("CL1"); 
pt2.ColumnLabels.Add("CL2"); 
pt2.ColumnLabels.Add("CL3"); 
pt2.Values.Add("V").SummaryFormula = XL.XLPivotSummary.Sum;