ClosedXML – 创build多个数据透视表

我试图将一些数据导出到Excel数据表S1其数据在接下来的两张表S2 and S3显示为透视图。 我能够创build一个枢轴,它的工作原理是完美的。 但是,当我创build两个枢轴,随之而来的Excel文件呈现为损坏。

我的意思是腐败,

点击是,我得到这个 –

腐败

这里是我用来创build枢纽的代码 –

 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 C1, C2, C3. C4 and V是我参考表S1中的列名。

这个问题是由一个ClosedXML实现错误引起的。

通过使用以下片段(他们的数据透视表示例的修改版本)并在Excel中打开生成的文件,可以轻松地进行复制:

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

该错误位于XLWorkbook_Save.cs – GeneratePivotTables方法中:

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

由行workbookPart.Workbook.AppendChild(pivotCaches); 它将多个PivotCaches添加到workbookPart.Workbook同时允许包含0或1。

说到这里,解决这个问题的唯一方法就是在源代码中修改上面的方法,如下所示:

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

更新:好消息是,我的post引发了由Francois Botha 修复的ClosedXML源代码库 (也归功于petelids谁把它带到那里),所以你可以从那里的代码,直到他们的下一个版本,希望将其包括。

尝试这种修改。 我在附注中添加了一行。 另外,我认为AddNew()方法可能有错误的工作表引用? 您可能一直在尝试在另一个顶部添加数据透视表。 这可能是真正的问题,而不是我添加的附加路线。

 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;