Skip to content

Commit

Permalink
fix: RowSpan should work with Excel Export and merge cells (#1819)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding authored Jan 24, 2025
1 parent 46541d6 commit 8b0d4a3
Show file tree
Hide file tree
Showing 12 changed files with 702 additions and 110 deletions.
4 changes: 4 additions & 0 deletions demos/vanilla/src/examples/example32.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ <h3 class="title is-3">
<span class="mdi mdi-pencil-outline"></span>
<span>Toggle Editing: <span id="isEditable" class="text-italic" textcontent.bind="isEditable">false</span></span>
</button>
<button class="button is-small" data-test="export-excel-btn" onclick.trigger="exportToExcel()">
<span class="mdi mdi-file-excel-outline text-success"></span>
<span>Export to Excel</span>
</button>
</div>
</section>

Expand Down
8 changes: 7 additions & 1 deletion demos/vanilla/src/examples/example32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default class Example32 {
isEditable = false;
gridOptions: GridOption;
dataset: any[] = [];
excelExportService: ExcelExportService;
sgb: SlickVanillaGridBundle;
gridContainerElm: HTMLDivElement;
metadata: ItemMetadata | Record<number, ItemMetadata> = {
Expand Down Expand Up @@ -110,6 +111,7 @@ export default class Example32 {

constructor() {
this._bindingEventService = new BindingEventService();
this.excelExportService = new ExcelExportService();
}

attached() {
Expand Down Expand Up @@ -165,7 +167,7 @@ export default class Example32 {
enableColumnReorder: true,
enableCellRowSpan: true,
enableExcelExport: true,
externalResources: [new ExcelExportService()],
externalResources: [this.excelExportService],
enableExcelCopyBuffer: true,
autoEdit: true,
editable: false,
Expand All @@ -184,6 +186,10 @@ export default class Example32 {
};
}

exportToExcel() {
this.excelExportService.exportToExcel({ filename: 'export', format: 'xlsx' });
}

navigateDown() {
this.sgb.slickGrid?.navigateDown();
}
Expand Down
194 changes: 175 additions & 19 deletions demos/vanilla/src/examples/example33.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type Column, type Formatter, type GridOption, type ItemMetadata } from '@slickgrid-universal/common';
import { BindingEventService } from '@slickgrid-universal/binding';
import { type Column, type Formatter, type GridOption, type ItemMetadata } from '@slickgrid-universal/common';
import { ExcelExportService } from '@slickgrid-universal/excel-export';
import { Slicker, type SlickVanillaGridBundle } from '@slickgrid-universal/vanilla-bundle';

import { ExampleGridOptions } from './example-grid-options.js';
Expand All @@ -10,6 +11,9 @@ const NB_ITEMS = 500;
const rowCellValueFormatter: Formatter = (row, cell, value) => {
return `<div class="cellValue">${value.toFixed(2)}</div><div class="valueComment">${row}.${cell}</div>`;
};
const rowCellValueExportFormatter: Formatter = (_row, _cell, value) => {
return value.toFixed(2);
};

export default class Example33 {
private _bindingEventService: BindingEventService;
Expand Down Expand Up @@ -85,48 +89,198 @@ export default class Example33 {
initializeGrid() {
this.columnDefinitions = [
{ id: 'title', name: 'Title', field: 'title', minWidth: 80 },
{ id: 'revenueGrowth', name: 'Revenue Growth', field: 'revenueGrowth', formatter: rowCellValueFormatter, minWidth: 120 },
{
id: 'revenueGrowth',
name: 'Revenue Growth',
field: 'revenueGrowth',
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
minWidth: 120,
},
{
id: 'pricingPolicy',
name: 'Pricing Policy',
field: 'pricingPolicy',
minWidth: 110,
sortable: true,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'policyIndex',
name: 'Policy Index',
field: 'policyIndex',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'expenseControl',
name: 'Expense Control',
field: 'expenseControl',
minWidth: 110,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'excessCash',
name: 'Excess Cash',
field: 'excessCash',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'netTradeCycle',
name: 'Net Trade Cycle',
field: 'netTradeCycle',
minWidth: 110,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'costCapital',
name: 'Cost of Capital',
field: 'costCapital',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'revenueGrowth2',
name: 'Revenue Growth',
field: 'revenueGrowth2',
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
minWidth: 120,
},
{ id: 'policyIndex', name: 'Policy Index', field: 'policyIndex', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'expenseControl', name: 'Expense Control', field: 'expenseControl', minWidth: 110, formatter: rowCellValueFormatter },
{ id: 'excessCash', name: 'Excess Cash', field: 'excessCash', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'netTradeCycle', name: 'Net Trade Cycle', field: 'netTradeCycle', minWidth: 110, formatter: rowCellValueFormatter },
{ id: 'costCapital', name: 'Cost of Capital', field: 'costCapital', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'revenueGrowth2', name: 'Revenue Growth', field: 'revenueGrowth2', formatter: rowCellValueFormatter, minWidth: 120 },
{
id: 'pricingPolicy2',
name: 'Pricing Policy',
field: 'pricingPolicy2',
minWidth: 110,
sortable: true,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'policyIndex2',
name: 'Policy Index',
field: 'policyIndex2',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'expenseControl2',
name: 'Expense Control',
field: 'expenseControl2',
minWidth: 110,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'excessCash2',
name: 'Excess Cash',
field: 'excessCash2',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'netTradeCycle2',
name: 'Net Trade Cycle',
field: 'netTradeCycle2',
minWidth: 110,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'costCapital2',
name: 'Cost of Capital',
field: 'costCapital2',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'revenueGrowth3',
name: 'Revenue Growth',
field: 'revenueGrowth3',
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
minWidth: 120,
},
{ id: 'policyIndex2', name: 'Policy Index', field: 'policyIndex2', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'expenseControl2', name: 'Expense Control', field: 'expenseControl2', minWidth: 110, formatter: rowCellValueFormatter },
{ id: 'excessCash2', name: 'Excess Cash', field: 'excessCash2', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'netTradeCycle2', name: 'Net Trade Cycle', field: 'netTradeCycle2', minWidth: 110, formatter: rowCellValueFormatter },
{ id: 'costCapital2', name: 'Cost of Capital', field: 'costCapital2', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'revenueGrowth3', name: 'Revenue Growth', field: 'revenueGrowth3', formatter: rowCellValueFormatter, minWidth: 120 },
{
id: 'pricingPolicy3',
name: 'Pricing Policy',
field: 'pricingPolicy3',
minWidth: 110,
sortable: true,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'policyIndex3',
name: 'Policy Index',
field: 'policyIndex3',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'expenseControl3',
name: 'Expense Control',
field: 'expenseControl3',
minWidth: 110,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'excessCash3',
name: 'Excess Cash',
field: 'excessCash3',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'netTradeCycle3',
name: 'Net Trade Cycle',
field: 'netTradeCycle3',
minWidth: 110,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{
id: 'costCapital3',
name: 'Cost of Capital',
field: 'costCapital3',
minWidth: 100,
exportCustomFormatter: rowCellValueExportFormatter,
formatter: rowCellValueFormatter,
type: 'number',
},
{ id: 'policyIndex3', name: 'Policy Index', field: 'policyIndex3', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'expenseControl3', name: 'Expense Control', field: 'expenseControl3', minWidth: 110, formatter: rowCellValueFormatter },
{ id: 'excessCash3', name: 'Excess Cash', field: 'excessCash3', minWidth: 100, formatter: rowCellValueFormatter },
{ id: 'netTradeCycle3', name: 'Net Trade Cycle', field: 'netTradeCycle3', minWidth: 110, formatter: rowCellValueFormatter },
{ id: 'costCapital3', name: 'Cost of Capital', field: 'costCapital3', minWidth: 100, formatter: rowCellValueFormatter },
];

this.gridOptions = {
Expand All @@ -141,6 +295,8 @@ export default class Example33 {
getRowMetadata: this.renderDifferentColspan.bind(this),
},
},
enableExcelExport: true,
externalResources: [new ExcelExportService()],
rowTopOffsetRenderType: 'top', // rowspan doesn't render well with 'transform', default is 'top'
};
}
Expand Down
10 changes: 9 additions & 1 deletion demos/vue/src/components/Example43.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { type Column, Editors, type GridOption, type ItemMetadata, SlickgridVue,
import { onBeforeMount, ref, type Ref } from 'vue';
const isEditable = ref(false);
const excelExportService = new ExcelExportService();
const gridOptions = ref<GridOption>();
const columnDefinitions: Ref<Column[]> = ref([]);
const dataset = ref<any[]>([]);
Expand Down Expand Up @@ -142,7 +143,7 @@ function defineGrid() {
enableColumnReorder: true,
enableCellRowSpan: true,
enableExcelExport: true,
externalResources: [new ExcelExportService()],
externalResources: [excelExportService],
enableExcelCopyBuffer: true,
autoEdit: true,
editable: false,
Expand All @@ -161,6 +162,10 @@ function defineGrid() {
};
}
function exportToExcel() {
excelExportService.exportToExcel({ filename: 'export', format: 'xlsx' });
}
function navigateDown() {
vueGrid?.slickGrid?.navigateDown();
}
Expand Down Expand Up @@ -481,6 +486,9 @@ function vueGridReady(grid: SlickgridVueInstance) {
>Toggle Editing: <span id="isEditable" class="text-italic">{{ isEditable }}</span></span
>
</button>
<button class="btn btn-outline-secondary btn-sm btn-icon mx-1" data-test="export-excel-btn" @click="exportToExcel()">
<i class="mdi mdi-file-excel-outline text-success"></i> Export to Excel
</button>

<slickgrid-vue
v-model:options="gridOptions"
Expand Down
Loading

0 comments on commit 8b0d4a3

Please sign in to comment.