Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PivotTable: Support multiple values #2578

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Rablet
Copy link

@Rablet Rablet commented Nov 1, 2023

Summary

This adds support for multiple values in pivot tables.
It also allows not supplying any columns. This mimics the built-in Excel functionality where it populates the columns field with "Values".

Limitation: It is not currently possible to provide multiple values AND any columns.

With the first implementation checked in yesterday it is not possible to use multiple values. This PR removes that limitation (as long as custom columns are not used)

Test plan

I created a PivotTable with multiple values and no columns without problems.
I crated a PivotTable with one value and multiple columns without problems

@Siemienik
Copy link
Member

@Rablet Thank you for development that, for more implementation details you can drive into #2575 :)

From my end, I required tests which proves and concrete the behaviour in the future. Would you like to add it?

Thanks 👍

@Rablet
Copy link
Author

Rablet commented Nov 13, 2023

Absolutely! Please see below:

1: Multiple values, no columns:

const ExcelJS = require('exceljs');

const createWorkbook = async () => {
    const workbook = new ExcelJS.Workbook();
    workbook.calcProperties.fullCalcOnLoad = true;

    const worksheet1 = workbook.addWorksheet('Sheet1');
    worksheet1.addRows([
        ['Description', 'Initial Cost', 'VAT', 'Total',],
        ['Potatoes', 10, 2, 12],
        ['Potatoes', 10, 2, 12],
        ['Potatoes', 10, 2, 12],
        ['Grapes', 20, 4, 24],
        ['Grapes', 20, 4, 24],
        ['Strawberries', 15, 3, 18],
    ]);

    const worksheet2 = workbook.addWorksheet('Sheet2');
    worksheet2.addPivotTable({
        sourceSheet: worksheet1,
        rows: ['Description'],
        columns: [],
        values: ['Initial Cost', 'VAT', 'Total'],
        metric: 'sum',
    });

    await workbook.xlsx.writeFile("PivotWithMultipleValues.xlsx");
}
createWorkbook();

image

2: Attempt with multiple values & columns:

 worksheet2.addPivotTable({
        sourceSheet: worksheet1,
        rows: ['Description'],
        columns: ['Description', 'Initial Cost'],
        values: ['Initial Cost', 'VAT', 'Total'],
        metric: 'sum',
    });

Output:

Warning: Pivot Table support is experimental. 
Please leave feedback at https://github.com/exceljs/exceljs/discussions/2575
/Users/robin/dev/exceljs/lib/doc/pivot-table.js:81
    throw new Error(
          ^

Error: It is currently not possible to have multiple values when columns are specified. Please either supply an empty array for columns or a single value.
    at validate (/Users/robin/dev/exceljs/lib/doc/pivot-table.js:81:11)
    at makePivotTable (/Users/robin/dev/exceljs/lib/doc/pivot-table.js:20:3)
    at Worksheet.addPivotTable (/Users/robin/dev/exceljs/lib/doc/worksheet.js:821:24)
    at createWorkbook (/Users/robin/dev/nodeexceldemo/index.js:21:16)
    at Object.<anonymous> (/Users/robin/dev/nodeexceldemo/index.js:31:1)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47

3: Showing that your scenario from the original PR still works:

const Excel = require('exceljs');

const workbook = new Excel.Workbook();

const worksheet1 = workbook.addWorksheet('Sheet1');
worksheet1.addRows([
    ['A', 'B', 'C', 'D', 'E'],
    ['a1', 'b1', 'c1', 4, 5],
    ['a1', 'b2', 'c1', 4, 5],
    ['a2', 'b1', 'c2', 14, 24],
    ['a2', 'b2', 'c2', 24, 35],
    ['a3', 'b1', 'c3', 34, 45],
    ['a3', 'b2', 'c3', 44, 45],
]);

const worksheet2 = workbook.addWorksheet('Sheet2');
worksheet2.addPivotTable({
    // Source data: entire sheet range; header in first row
    sourceSheet: worksheet1,
    // Pivot table fields: via header row in `worksheet1`
    rows: ['A', 'B'],
    columns: ['C'],
    values: ['E'], // Exactly 1 field
    metric: 'sum', // Metric: 'sum' only
});

workbook.xlsx.writeFile("RegressionTest.xlsx");

image

Please let me know if you'd like to see anything else.

@Rablet
Copy link
Author

Rablet commented Dec 18, 2023

Are you all good with this PR or do you need something else?

@budaesandrei
Copy link

is this going to get merged anytime soon?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants