Skip to content

Commit

Permalink
fix: RowSpan should work with Excel Export and merge cells (#456)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding authored Jan 25, 2025
1 parent e2bbe6a commit c68b606
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 114 deletions.
30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@
"/src/slickgrid-react"
],
"dependencies": {
"@slickgrid-universal/common": "~5.12.0",
"@slickgrid-universal/custom-footer-component": "~5.12.0",
"@slickgrid-universal/empty-warning-component": "~5.12.0",
"@slickgrid-universal/common": "~5.12.1",
"@slickgrid-universal/custom-footer-component": "~5.12.1",
"@slickgrid-universal/empty-warning-component": "~5.12.1",
"@slickgrid-universal/event-pub-sub": "~5.12.0",
"@slickgrid-universal/pagination-component": "~5.12.0",
"@slickgrid-universal/row-detail-view-plugin": "~5.12.0",
"@slickgrid-universal/pagination-component": "~5.12.1",
"@slickgrid-universal/row-detail-view-plugin": "~5.12.1",
"dequal": "^2.0.3",
"i18next": "^23.16.8",
"sortablejs": "^1.15.6"
Expand All @@ -103,13 +103,13 @@
"@formkit/tempo": "^0.1.2",
"@popperjs/core": "^2.11.8",
"@release-it/conventional-changelog": "^10.0.0",
"@slickgrid-universal/composite-editor-component": "~5.12.0",
"@slickgrid-universal/custom-tooltip-plugin": "~5.12.0",
"@slickgrid-universal/excel-export": "~5.12.0",
"@slickgrid-universal/graphql": "~5.12.0",
"@slickgrid-universal/odata": "~5.12.0",
"@slickgrid-universal/rxjs-observable": "~5.12.0",
"@slickgrid-universal/text-export": "~5.12.0",
"@slickgrid-universal/composite-editor-component": "~5.12.1",
"@slickgrid-universal/custom-tooltip-plugin": "~5.12.1",
"@slickgrid-universal/excel-export": "~5.12.1",
"@slickgrid-universal/graphql": "~5.12.1",
"@slickgrid-universal/odata": "~5.12.1",
"@slickgrid-universal/rxjs-observable": "~5.12.1",
"@slickgrid-universal/text-export": "~5.12.1",
"@types/fnando__sparkline": "^0.3.7",
"@types/i18next-xhr-backend": "^1.4.2",
"@types/node": "^22.10.10",
Expand All @@ -125,7 +125,7 @@
"cypress": "^14.0.0",
"cypress-real-events": "^1.14.0",
"dompurify": "^3.2.3",
"eslint": "^9.18.0",
"eslint": "^9.19.0",
"eslint-plugin-cypress": "^4.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-n": "^17.15.1",
Expand All @@ -141,7 +141,7 @@
"react-i18next": "^15.4.0",
"react-router-dom": "^7.1.3",
"regenerator-runtime": "^0.14.1",
"release-it": "^18.1.1",
"release-it": "^18.1.2",
"rimraf": "^5.0.10",
"rxjs": "^7.8.1",
"sass": "^1.83.4",
Expand All @@ -158,4 +158,4 @@
"resolutions": {
"caniuse-lite": "1.0.30001695"
}
}
}
10 changes: 9 additions & 1 deletion src/examples/slickgrid/Example43.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default function Example43() {
const [isEditable, setIsEditable] = useState<boolean>(false);
const [showSubTitle, setShowSubTitle] = useState(false);
const [dataset] = useState(loadData());
const excelExportService = new ExcelExportService();
const metadata: Record<number, ItemMetadata> = {
// 10001: Davolio
0: {
Expand Down Expand Up @@ -141,7 +142,7 @@ export default function Example43() {
enableColumnReorder: true,
enableCellRowSpan: true,
enableExcelExport: true,
externalResources: [new ExcelExportService()],
externalResources: [excelExportService],
enableExcelCopyBuffer: true,
autoEdit: true,
editable: false,
Expand All @@ -159,6 +160,10 @@ export default function Example43() {
rowTopOffsetRenderType: 'top', // rowspan doesn't render well with 'transform', default is 'top'
};

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

function navigateDown() {
reactGrid?.slickGrid?.navigateDown();
}
Expand Down Expand Up @@ -479,6 +484,9 @@ export default function Example43() {
<span className="mdi mdi-pencil-outline"></span>
<span>Toggle Editing: <span id="isEditable" className="text-italic">{isEditable + ''}</span></span>
</button>
<button className="btn btn-outline-secondary btn-sm btn-icon mx-1" data-test="export-excel-btn" onClick={() => exportToExcel()}>
<i className="mdi mdi-file-excel-outline text-success"></i> Export to Excel
</button>

<SlickgridReact gridId="grid43"
columnDefinitions={columnDefinitions}
Expand Down
195 changes: 174 additions & 21 deletions src/examples/slickgrid/Example44.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ExcelExportService } from '@slickgrid-universal/excel-export';
import {
type Column,
type Formatter,
Expand Down Expand Up @@ -62,55 +63,205 @@ export default function Example44() {
loadData(500);
}, []);

Check warning on line 64 in src/examples/slickgrid/Example44.tsx

View workflow job for this annotation

GitHub Actions / Node 20

React Hook useEffect has a missing dependency: 'loadData'. Either include it or remove the dependency array

const rowCellValueFormatter: Formatter = (row, cell, value) => {
return `<div class="cellValue">${value.toFixed(2)}</div><div class="valueComment">${row}.${cell}</div>`;
};
const rowCellValueFormatter: Formatter = (row, cell, value) =>
`<div class="cellValue">${value.toFixed(2)}</div><div class="valueComment">${row}.${cell}</div>`;
const rowCellValueExportFormatter: Formatter = (_row, _cell, value) => value.toFixed(2);

// the columns field property is type-safe, try to add a different string not representing one of DataItems properties
const columnDefinitions: Column[] = [
{ 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 },
];

const gridOptions: GridOption = {
Expand All @@ -125,6 +276,8 @@ export default function Example44() {
getRowMetadata: (item: any, row: any) => renderDifferentColspan(item, row),
},
},
enableExcelExport: true,
externalResources: [new ExcelExportService()],
rowTopOffsetRenderType: 'top', // rowspan doesn't render well with 'transform', default is 'top'
};

Expand Down
Loading

0 comments on commit c68b606

Please sign in to comment.