Print Plugin

@dayflow-pro/plugin-print adds a built-in print dialog and multi-format export flow for DayFlow. It provides interactive page previews, paper size and orientation controls, trackpad pinch zoom, live data preview for spreadsheets, and headless programmatic export.

FormatOutput
printBrowser print dialog, accurately sized to the selected paper; print on paper or save as PDF
pngHigh-resolution image per printed page; multi-page exports download as a ZIP archive
xlsxNative Excel workbook: an Events sheet (one row per event) and a Summary per calendar
icsStandard iCalendar file for Google Calendar, Apple Calendar, Outlook, and other apps

Try the live demo.

Installation

npm install @dayflow-pro/plugin-print
pnpm add @dayflow-pro/plugin-print
yarn add @dayflow-pro/plugin-print
bun add @dayflow-pro/plugin-print

Refer to the Pro Installation guide for licensing and setup details.

Be sure to import the component styles in your application:

import '@dayflow-pro/plugin-print/dist/styles.components.css';

Basic usage

import { DayFlowCalendar, useCalendarApp } from '@dayflow/react';
import { createPrintPlugin } from '@dayflow-pro/plugin-print';
import '@dayflow-pro/plugin-print/dist/styles.components.css';

function App() {
  const printPlugin = createPrintPlugin({
    defaultOptions: {
      miniCalendar: true,
      calendarKeys: true,
      textSize: 'medium',
    },
  });

  const calendar = useCalendarApp({
    views: [
      /* your views */
    ],
    plugins: [printPlugin],
  });

  return (
    <>
      <button onClick={() => calendar.app.openPrintDialog()}>Print</button>
      <button onClick={() => calendar.app.openPrintDialog({ format: 'xlsx' })}>
        Export Excel
      </button>
      <DayFlowCalendar calendar={calendar} />
    </>
  );
}
<template>
  <div>
    <button @click="calendar.app.openPrintDialog()">Print</button>
    <button @click="calendar.app.openPrintDialog({ format: 'xlsx' })">
      Export Excel
    </button>
    <DayFlowCalendar :calendar="calendar" />
  </div>
</template>

<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';
import { createPrintPlugin } from '@dayflow-pro/plugin-print';
import '@dayflow-pro/plugin-print/dist/styles.components.css';

const printPlugin = createPrintPlugin({
  defaultOptions: {
    miniCalendar: true,
    calendarKeys: true,
    textSize: 'medium',
  },
});

const calendar = useCalendarApp({
  views: [
    /* your views */
  ],
  plugins: [printPlugin],
});
</script>
import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';
import { createPrintPlugin } from '@dayflow-pro/plugin-print';
import '@dayflow-pro/plugin-print/dist/styles.components.css';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [DayFlowCalendarModule],
  template: `
    <button (click)="calendar.app.openPrintDialog()">Print</button>
    <button (click)="calendar.app.openPrintDialog({ format: 'xlsx' })">Export Excel</button>
    <dayflow-calendar [calendar]="calendar"></dayflow-calendar>
  `
})
export class AppComponent {
  printPlugin = createPrintPlugin({
    defaultOptions: {
      miniCalendar: true,
      calendarKeys: true,
      textSize: 'medium',
    },
  });

  calendar = {
    views: [
      /* your views */
    ],
    plugins: [this.printPlugin]
  };
}
<script>
  import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';
  import { createPrintPlugin } from '@dayflow-pro/plugin-print';
  import '@dayflow-pro/plugin-print/dist/styles.components.css';

  const printPlugin = createPrintPlugin({
    defaultOptions: {
      miniCalendar: true,
      calendarKeys: true,
      textSize: 'medium',
    },
  });

  const calendar = useCalendarApp({
    views: [
      /* your views */
    ],
    plugins: [printPlugin],
  });
</script>

<button onclick={() => calendar.app.openPrintDialog()}>Print</button>
<button onclick={() => calendar.app.openPrintDialog({ format: 'xlsx' })}>
  Export Excel
</button>
<DayFlowCalendar {calendar} />

The plugin registers helper methods directly onto the calendar instance:

// Open dialog with default format
await calendar.app.openPrintDialog();

// Open dialog pre-seeded with format or custom view
await calendar.app.openPrintDialog({ format: 'xlsx', view: 'month' });

// Trigger native print flow
await calendar.app.print();

// Programmatic export without mounting the dialog
const result = await calendar.app.exportCalendar({
  format: 'png',
  view: 'week',
});

Features

  • 4 Export Formats: Print/PDF, PNG (single or zipped multi-page), Excel (.xlsx), and iCalendar (.ics).
  • 9 Paper Sizes: A3, A4, A5, B3, B4, B5, Letter, Legal, Tabloid.
  • Interactive Preview Dialog: Sized page preview, trackpad pinch zoom, panning, and auto layout adjustments.
  • Live Data Preview: Switching to xlsx or ics presents an interactive tabular data preview inside the dialog before downloading.
  • Headless Programmatic Export: Call calendar.app.exportCalendar() or printPlugin.api.export() to generate files or receive Blobs directly from code.
  • Calendar & Category Filtering: Filter visible calendars, all-day events, and timed events.
  • Global Shortcut: Press Cmd + P or Ctrl + P to trigger the print dialog.

Supported print views

ViewDescription
dayPrints one or more selected days.
weekPrints a week-style layout.
monthPrints a monthly grid layout.
year-fixed-weekYear overview using fixed weekly rows. Defaults to landscape.
year-canvasDense year overview optimized for portrait layout.

When the dialog opens, it automatically derives its initial view from the active calendar view:

  • Month view -> month
  • Week view -> week
  • Day view -> day
  • Year view -> year-fixed-week

Exporting from code (Headless)

Use calendar.app.exportCalendar() (or printPlugin.api.export()) to export without opening the dialog UI:

const result = await calendar.app.exportCalendar({
  format: 'xlsx',
  view: 'month',
  startDate: new Date(2026, 8, 1),
  endDate: new Date(2026, 11, 1), // September through December
  calendarIds: ['work', 'personal'],
  download: true, // set to false to receive result.blob without triggering a browser download
  pixelRatio: 3, // for PNG output (1 = 96 DPI)
  onProgress: ({ completed, total }) => {
    console.log(`Rendered page ${completed} of ${total}`);
  },
});

console.log(result.filename); // 'calendar-2026-09_2026-12.xlsx'
console.log(result.eventCount); // number of exported events
console.log(result.pageCount); // number of rendered pages (0 for xlsx and ics)
console.log(result.blob); // Blob instance when download: false

CalendarExportRequest Options

OptionTypeDefaultDescription
format'print' | 'png' | 'xlsx' | 'ics'RequiredTarget export format.
viewPrintViewCurrent viewLayout to render (day, week, month, year-fixed-week, year-canvas).
paperPaperSizeCurrent selectionPaper size (A3, A4, A5, B3, B4, B5, Letter, Legal, Tabloid).
orientation'portrait' | 'landscape'View defaultPage orientation.
startDateDateCurrent dateStart date of the exported range.
endDateDateAuto-calculatedEnd date of the exported range.
calendarIdsstring[]All calendarsIncluded calendar IDs.
optionsPartial<CalendarPrintOptions>Plugin defaultsTypography, legend, and event filter options.
filenamestringAuto-generatedCustom file name without extension.
downloadbooleantrueWhen false, returns result.blob without triggering browser save.
pixelRationumber3PNG resolution multiplier (1 renders at 96 DPI).
onProgress(progress: { completed: number; total: number }) => void—Progress callback invoked after each PNG page is rasterized.
signalAbortSignal—AbortSignal to cancel multi-page generation midway.

Plugin configuration

Pass options to createPrintPlugin(config):

const printPlugin = createPrintPlugin({
  formats: ['print', 'png', 'xlsx', 'ics'], // formats shown in dialog and their order
  filename: ({ format, view, rangeStart, rangeEnd }) => `schedule-${view}`,
  pixelRatio: 3,
  defaultOptions: {
    miniCalendar: true,
    calendarKeys: true,
    textSize: 'medium',
  },
});
PropertyTypeDefaultDescription
enabledbooleantrueDisables the plugin completely when false.
formatsCalendarExportFormat[]['print', 'png', 'xlsx', 'ics']Formats displayed in the dialog selector.
filenamestring | ((context: CalendarExportFilenameContext) => string)—Custom base name or generator function for exported files.
pixelRationumber3Default PNG resolution multiplier.
defaultOptionsPartial<CalendarPrintOptions>—Preloaded print and visibility options.
licensePackageLicenseConfig—License configuration when not registered globally.

CalendarPrintOptions

PropertyTypeDefaultDescription
allDayEventsbooleantrueInclude all-day events in output.
timedEventsbooleantrueInclude timed events in output.
miniCalendarbooleantrueDisplay mini calendar in the print header.
calendarKeysbooleantrueDisplay calendar category legend.
blackAndWhitebooleanfalseRender in monochrome without colors.
textSize'small' | 'medium' | 'large'mediumAdjust typography scale and layout density.

Plugin API

The plugin exposes an api object on the plugin instance:

type PrintPluginApi = {
  open: (options?: PrintDialogOpenOptions) => void;
  close: () => void;
  print: (config?: CalendarPrintConfigInput) => void;
  export: (request: CalendarExportRequest) => Promise<CalendarExportResult>;
};

Additional notes

  • PDF Export: In the browser print dialog (print), choose "Save as PDF". This produces a vector PDF with selectable, searchable text.
  • Timezone handling: Exported Excel times respect the calendar's configured timeZone. ICS files adhere to RFC 5545 specifications (zoned times formatted in UTC, floating times in local representation).
  • Retina PNGs & Fonts: PNG rendering embeds reachable web fonts automatically and uses high-DPI rasterization (pixelRatio: 3 by default).
  • Interactive Preview Gestures: In the preview dialog, use trackpad pinch gestures (or Ctrl/Cmd + mouse wheel) to zoom into specific areas, and click-drag to pan around pages.

On this page