node.jsexceljs

Export with dynamic column names in Excel js library Node js


I am trying to export excel file with dynamic columns and rows some columns contain values or some not. Please help me to solve that issue. I am using nodejs exceljs library.

It's exporting data with static columns correctly but when I am trying to map dynamic columns then worksheet.addRow creating issue with dynamic columns mapping.

Thanks in advance.

Problem here when I assign dynamic columns key mapping. That is not supporting here.

worksheet.addRow({
                    goal_name: m.name,
                    goal_description: m.purpose,
                    created: m.created,
                    privacy_types_id: m.privacy_types_id,
                    priority: m.priority,
                    progress: m.stats.progress,
                    /*should be dyanmic key mapping all below 
                      fields*/
                    CustomField1: item.value,
                    CustomField2: item.value,
                    CustomField3: item.value,
                    CustomField4: item.value,
                    CustomField5: item.value,
                });

This is my nodejs code:

 const stream = new Stream.PassThrough();
    const workbook = new excel.stream.xlsx.WorkbookWriter({
        stream: stream,
    });

let worksheet = workbook.addWorksheet("Goals");

// mapping static columns names
worksheet.columns = [
    { header: "Name", key: "goal_name", width: 15 },
    { header: "Description", key: "goal_description", width: 15 },
    { header: "Created Date", key: "created", width: 20 },
    { header: 'Privacy Type', key: 'privacy_types_id', width: 20 },
    { header: 'Priority', key: 'priority', width: 20 },
    { header: 'Progress', key: 'progress', width: 20 },
];
// let rows = [];
// Adding dynamic columns
_goals.forEach((m, pIndex) => {
    if (m.fields !== null && m.fields.length > 0) {
        let i = 1;
        m.fields.forEach((item, index) => {
            let customFieldName = item.field_name.replace(/\s/g, '_');;
            let customFieldValue = item.value;
            let getExistingColumns = worksheet.columns;
            const found = getExistingColumns.some(el => el._header === item.field_name);
            var CustomField = 'CustomField' + i;
            if (!found) {
                let newColumn = worksheet.getColumn(worksheet.columns.length + 1);
                newColumn.header = item.field_name;
                newColumn.key = 'CustomField' + i;
                newColumn.width = 15;
                //worksheet.columns.push(newColumn);
                i++;
            }
        });
    }
});
// Adding goals rows
_goals.forEach((m, pIndex) => {
    if (m.fields !== null && m.fields.length > 0) {
        let i = 1;
        m.fields.forEach((item, index) => {
            let customFieldName = item.field_name.replace(/\s/g, '_');;
            let customFieldValue = item.value;
            let getExistingColumns = worksheet.columns;
            const found = getExistingColumns.some(el => el._header === item.field_name);
            var CustomField = 'CustomField' + i;

            worksheet.addRow({
                goal_name: m.name,
                goal_description: m.purpose,
                created: m.created,
                privacy_types_id: m.privacy_types_id,
                priority: m.priority,
                progress: m.stats.progress,
                CustomField1: item.value,
                CustomField2: item.value,
                CustomField3: item.value,
                CustomField4: item.value,
                CustomField5: item.value,
            });

        });
    }
    else {
        worksheet.addRow({
            goal_name: m.name,
            goal_description: m.purpose,
            created: m.created,
            privacy_types_id: m.privacy_types_id,
            priority: m.priority,
            progress: m.stats.progress,
        });
    }
});

worksheet.commit();
workbook.commit();

const file_uuid = uuidv4();
const name = 'Goals list';
const mimetype = 'application/vnd.ms-excel';
const ext = 'xlsx';

Solution

  • To dynamically map the columns in your Excel file using the exceljs library in Node.js, you can try doing this:

        let dynamicColumns = [
      { header: "Name", key: "goal_name", width: 15 },
      { header: "Description", key: "goal_description", width: 15 },
      { header: "Created Date", key: "created", width: 20 },
      { header: 'Privacy Type', key: 'privacy_types_id', width: 20 },
      { header: 'Priority', key: 'priority', width: 20 },
      { header: 'Progress', key: 'progress', width: 20 },
    ];
    
        m.fields.forEach((item, index) => {
      let customFieldName = item.field_name.replace(/\s/g, '_');
      let customFieldValue = item.value;
      const found = dynamicColumns.some(col => col.key === customFieldName);
      
      if (!found) {
        dynamicColumns.push({
          header: item.field_name,
          key: customFieldName,
          width: 15
        });
      }
    });
    
    
    worksheet.columns = dynamicColumns;
    
    _goals.forEach((m, pIndex) => {
      if (m.fields !== null && m.fields.length > 0) {
        let rowValues = {
          goal_name: m.name,
          goal_description: m.purpose,
          created: m.created,
          privacy_types_id: m.privacy_types_id,
          priority: m.priority,
          progress: m.stats.progress,
        };
    
        m.fields.forEach((item, index) => {
          let customFieldName = item.field_name.replace(/\s/g, '_');
          rowValues[customFieldName] = item.value;
        });
    
        worksheet.addRow(rowValues);
      } else {
        worksheet.addRow({
          goal_name: m.name,
          goal_description: m.purpose,
          created: m.created,
          privacy_types_id: m.privacy_types_id,
          priority: m.priority,
          progress: m.stats.progress,
        });
      }
    });