Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating pivot table using ClosedXML

I'm trying to create a Pivot table using ClosedXML V0.91.1, but I keep getting problems with my excel file having unreadable content and then the excel workbook removing my pivot table when clicking Yes below.

Error when opening excel file

Below is that shows when I hit Yes. It's removing my pivot table.

Excel removing unreadable content

My Pivot Table is getting data from a table that is created from a history of TFS Changesets. The changesets are set into a IEnumerable<Changeset> which is then converted into a DataTable object which include the column headings.

A table is then created from the DataTable which is the source of the PivotTable. This is the code that I'm using:

public bool CreateReport(IEnumerable<Changeset> changesets)
{
    workbook = new XLWorkbook();
    var sumSheet= workbook.Worksheets.Add("Summary");
    // Converting IEnumerable<Changeset> into DataTable
    DataTable changesetTable = ConvertToDataTable(changesets);
    // Table
    var sumTable = sumSheet.Cell(1, 1).InsertTable(changesetTable.AsEnumerable(), "SummaryTable", true);
    // Table - Formatting table
    tableWithData.Column("A").Cells(firstRow, lastRow).DataType = XLDataType.Number;
    tableWithData.Column("C").Cells(firstRow, lastRow).DataType = XLDataType.DateTime;
    tableWithData.Column("C").Cells(firstRow, lastRow).Style.DateFormat.Format = "d-MMM-yyy";

    sumSheet.Columns().AdjustToContents();

    // Pivot Table
    var header = sumTable.Range(1, 1, 1, 6); // A1 to F1
    var range = sumTable.DataRange;
    var dataRange = sumSheet.Range(header.FirstCell(), range.LastCell());

    var pivotSheet = workbook.Worksheets.Add("History Report");

    var pivotTable = pivotSheet.PivotTables.AddNew("PivotTable", pivotSheet.Cell(1, 1), dataRange);

    // Pivot Table - Formatting table
    pivotTable.ShowPropertiesInTooltips = false;
    pivotTable.RepeatRowLabels = false;
    pivotTable.ShowGrandTotalsColumns = false;
    pivotTable.ShowGrandTotalsRows = false;
    pivotTable.ShowEmptyItemsOnRows = true;
    pivotTable.ShowEmptyItemsOnColumns = true;
    pivotTable.ShowExpandCollapseButtons = false;
    pivotTable.Layout = XLPivotLayout.Tabular;

    pivotTable.RowLabels.Add("Changeset");
    pivotTable.RowLabels.Add("Committer");
    pivotTable.RowLabels.Add("Date");
    pivotTable.RowLabels.Add("Comment");
    pivotTable.RowLabels.Add("File Changes");
    pivotTable.RowLabels.Add("Source");

    // Go off and save the workbook.
    bool saved = SaveFile();
    return saved;
}

I believe the problem is with how I am selecting the dataRange for the source of the Pivot Table.

    var header = sumTable.Range(1, 1, 1, 6); // A1 to F1
    var range = sumTable.DataRange;
    var dataRange = sumSheet.Range(header.FirstCell(), range.LastCell());

I followed the example found on their wiki, but it gives those errors with my implementation. The only difference between my problem and the example, is that I am getting my source for the Pivot Table from a DataTable, and I am only inserting values into RowLabels in my Pivot Table.

If it helps, this is how I convert the IEnumerable<Changeset> to a DataTable

private DataTable ConvertToDataTable(IEnumerable<Changeset> changesets)
{
    DataTable table = new DataTable();
    table.Columns.Add("Changeset", typeof(int));
    table.Columns.Add("Committer", typeof(string));
    table.Columns.Add("Date", typeof(DateTime));
    table.Columns.Add("Comment", typeof(string));
    table.Columns.Add("File Changes", typeof(string));
    table.Columns.Add("Source", typeof(string));

    foreach(Changeset changeset in changesets) // Loop over all changesets
    {
        int changesetID = changeset.ChangesetId;
        string committer = changeset.CommitterDisplayName;
        DateTime creationDate = changeset.CreationDate;
        string comment = changeset.Comment;
        foreach(Change change in changeset.Changes) // Loop over all Changes in changeset
        {
            string filename = change.Item.ServerItem.Substring(change.Item.ServerItem.LastIndexOf("/") + 1);
            table.Rows.Add(changesetID, committer, creationDate, comment, filename, change.Item.ServerItem);
        }
    }
    return table;
}
like image 328
Jimenemex Avatar asked Nov 24 '25 10:11

Jimenemex


2 Answers

If I recall correctly, a pivot table in ClosedXML should have at least one value field.

pivotTable.Values.Add("somefield");
like image 78
Francois Botha Avatar answered Nov 27 '25 00:11

Francois Botha


I know I am a bit late on this one, but in case anyone else tries to do this in future, my solution was as follows.

IXLPivotTable xlPvTable = TargetWorksheet.PivotTables.Add(
    "PivotTable123", 
    TargetWorksheet.Cell(1, 1), 
    SourceWorksheet.Range(1, 1, MainData.Rows.Count, MainData.Columns.Count)
);

Then add the ColumnLabel and RowLabels etc..

like image 39
Bill.F Avatar answered Nov 26 '25 23:11

Bill.F



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!