# Grid, Export, Rendering
URL: https://pro.rv-grid.com/guides/gantt/features/grid-export-rendering/
Source: src/content/docs/guides/gantt/features/grid-export-rendering.mdx
Description: Use Gantt row export mapping, column presets, status indicators, and context-menu extension recipes.
These helpers package common grid-side Gantt work without coupling your application to internal timeline layout data.

```ts
import {
  createGanttColumnPreset,
  createGanttContextMenuExtensionItems,
  createGanttExcelExportRecipe,
  createGanttPdfExcelReportingRecipe,
  createGanttTaskStatusIndicatorRecipe,
  createTaskStatusIndicators,
  mapGanttRowsToExcelExport,
} from '@revolist/revogrid-enterprise';
```

## Gantt Excel Export Mapping

Use `mapGanttRowsToExcelExport()` when exporting projected task rows. The mapper uses an allowlist of user-facing fields and skips renderer-only timeline metadata.

```ts
const rows = mapGanttRowsToExcelExport(taskRows, project, {
  includeResourceRows: false,
});

downloadWorkbook({
  sheetName: project.name,
  rows,
});
```

For shells that prefer a recipe object:

```ts
const recipe = createGanttExcelExportRecipe({
  rows: taskRows,
  project,
});

downloadWorkbook({
  fields: recipe.fieldNames,
  rows: recipe.rows,
});
```

## PDF And Excel Reporting

Use the combined reporting recipe when your app has separate toolbar buttons for stakeholder PDF reports and spreadsheet handoff. PDF uses the browser print dialog, so users can choose **Save as PDF**. Excel dispatches the Pro `export-excel` event, so include `ExportExcelPlugin` with the grid plugins.

```ts
import {
  GanttPlugin,
  createGanttPdfExcelReportingRecipe,
} from '@revolist/revogrid-enterprise';
import { ExportExcelPlugin } from '@revolist/revogrid-pro';

const grid = document.querySelector<HTMLRevoGridElement>('revo-grid');
const host = document.querySelector<HTMLElement>('#gantt-report');

if (!grid || !host) {
  throw new Error('Gantt report target was not found');
}

grid.plugins = [GanttPlugin, ExportExcelPlugin];
grid.gantt = project;

const reportRange = {
  startDate: '2026-05-01',
  endDate: '2026-05-31',
};

const reporting = createGanttPdfExcelReportingRecipe({
  grid,
  target: host,
  document,
  window,
  excel: {
    workbookName: `${project.name}.xlsx`,
  },
});

pdfButton.addEventListener('click', () => {
  const result = reporting.exportPdf(project, reportRange);

  if (!result.ok) {
    showExportError(result.reason);
  }
});

excelButton.addEventListener('click', () => {
  reporting.exportExcel({
    sheetName: 'Tasks',
  });
});
```

For a single "export report" action, call both commands together:

```ts
const result = reporting.exportReport(project, {
  range: { label: 'Executive status report' },
  excel: { sheetName: 'Task register' },
});

if (!result.pdf.ok) {
  showExportError(result.pdf.reason);
}
```

## Column Presets

Column presets group the default Gantt task-table columns into common planning views.

```ts
grid.columns = createGanttColumnPreset('schedule');
grid.source = [...taskRows];
```

Available presets include `core`, `schedule`, `dependencies`, `resources`, `baseline`, `cost`, `progress`, and `all`.

## Read-Only And Locked Indicators

Use indicator helpers to produce labels and class names for custom cell renderers.

```ts
const status = createTaskStatusIndicators({
  taskId: row.id,
  projectReadOnly,
  taskLocked: lockedTaskIds.has(row.id),
});

renderIndicatorCell({
  className: status.classNames.join(' '),
  title: status.label,
  indicators: status.indicators,
});
```

For multiple rows:

```ts
const indicatorRows = createGanttTaskStatusIndicatorRecipe({
  rows: taskRows,
  projectReadOnly,
  lockedTaskIds,
});
```

## Context Menu Extensions

Gantt installs separate RevoGrid Pro row and column context menus. Row menus are task-oriented (`Add`, `Convert to milestone`, `Indent`, `Outdent`, `Delete`). Main grid column menus expose search, sort, and filter actions. The pinned Gantt canvas column menu exposes timeline zoom controls.

Use the built-in context-menu helpers with `rowContextMenu` to add duplicate, assign-resource, export, or custom task actions.

```ts
const contextMenuItems = createGanttContextMenuExtensionItems({
  duplicate: {
    copyName: (task) => `${task.name ?? 'Task'} copy`,
  },
  delete: {
    confirm: (context) => window.confirm(`Delete ${context.task?.name ?? 'task'}?`),
    onDeleteTask: (context) => {
      if (context.taskId) {
        deleteTask(context.taskId);
      }
    },
  },
  assignResource: {
    onAssignResource: (context) => {
      if (context.taskId) {
        openResourcePicker(context.taskId);
      }
    },
  },
  export: {
    exportOptions: (context) => ({
      workbookName: 'gantt.xlsx',
      sheetName: context.task?.name ?? 'Gantt',
    }),
  },
});

grid.rowContextMenu = {
  ...grid.rowContextMenu,
  items: [...(grid.rowContextMenu?.items ?? []), ...contextMenuItems],
};
```

Disable individual items with `false`.

```ts
const exportOnly = createGanttContextMenuExtensionItems({
  duplicate: false,
  delete: false,
  assignResource: false,
  export: { name: 'Export visible Gantt tasks' },
});
```
