---
title: Integrate PDF Generator in Survey Creator
product: Survey Creator
description: Need to generate custom PDF forms? With SurveyJS UI components, you can build and export fillable or read-only forms right in your JavaScript app. View our demo to learn more.
framework: React
source: https://surveyjs.io/survey-creator/examples/integrate-pdf-generator/reactjs
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Integrate PDF Generator in Survey Creator (React)

[SurveyJS PDF Generator](https://surveyjs.io/pdf-generator/documentation/overview) is a JavaScript UI component that enables you to render SurveyJS surveys and forms as PDF files directly in a browser. You can print these PDF forms for offline use, such as at conferences and workshops, or share editable forms with respondents to complete online. This example demonstrates how you can integrate PDF Generator into Survey Creator to generate and preview PDF forms as you configure them.

## Install PDF Generator

PDF Generator is built upon the <a href="https://github.com/parallax/jsPDF#readme" target="_blank">jsPDF</a> library. Select and implement one of the following options to set up PDF Generator:

- Option 1: Insert the jsPDF and PDF Generator scripts within the `<head>` tag on your HTML page.

    ```html
    <head>
        <script src="https://unpkg.com/jspdf/dist/jspdf.umd.min.js"></script>
        <script src="https://unpkg.com/survey-pdf/survey.pdf.min.js"></script>
        <!-- ... -->
    </head>
    ```
- Option 2: Install the `survey-pdf` npm package.           
    The jsPDF npm package will be installed automatically as a dependency.

    ```sh
    npm install survey-pdf
    ```

## Add PDF Generator Settings to the Property Grid

PDF Generator settings allow you to customize page orientation, margins, font, and other document parameters (see [`IDocOptions`](https://surveyjs.io/pdf-generator/documentation/api-reference/idocoptions)). Survey Creator users can change these settings in the Property Grid. To make them available, [add corresponding custom properties](https://surveyjs.io/form-library/documentation/customize-question-types/add-custom-properties-to-a-form) to the `"survey"` class:

```js
Serializer.addProperty("survey", {
    name: "pdfOrientation",
    displayName: "Page orientation",
    type: "buttongroup",
    category: pdfCategoryName,
    categoryIndex: 800,
    default: "auto",
    choices: [ "auto", "p|Portrait", "l|Landscape" ],
    isSerializable: false
});
```

This demo also adds a custom `pdfIsPageBreak` property to the `"question"` class. When enabled for a question, this property inserts a page break before that question:

```js
Serializer.addProperty("question", {
    name: "pdfIsPageBreak:boolean",
    displayName: "Insert a page break before this element",
    category: pdfCategoryName,
    categoryIndex: 800,
    default: false,
    isSerializable: false
});
```

## Generate a PDF Form

To save a survey as a PDF document, follow the steps below:

1. Prepare the PDF document.               
Use the PDF settings from the survey being configured to build an [`IDocOptions`](https://surveyjs.io/pdf-generator/documentation/api-reference/idocoptions) object and apply other customizations to the document. 

1. Instantiate `SurveyPDF`.          
Pass a survey JSON schema and the `IDocOptions` object to the `SurveyPDF` constructor.

1. Call the `save(fileName)` method.            
This method saves a PDF document under a specified name on the user's device.

1. Add a custom toolbar button.        
Combine steps 1 to 3 into a single function and call it by a click on a [custom toolbar button](/survey-creator/examples/toolbar-customization/documentation).

Refer to the Code tab for a full code example.

## Files

### `public/index.html`

```html
<!-- Uncomment the following lines to enable Ace Editor in the JSON Editor tab -->
<!-- 
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ace.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ext-searchbox.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/theme-clouds_midnight.js"></script>
-->

<div id="surveyCreatorContainer" style="position: absolute; height: 100%; width: 100%"></div>
```

### `src/survey_json.js`

```js
export const formJSON = {
  "title": "NPS Survey",
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "rating",
          "name": "nps-score",
          "title": "On a scale from 0 to 10, how likely are you to recommend us to a friend or colleague?",
          "rateMin": 0,
          "rateMax": 10,
          "minRateDescription": "Very unlikely",
          "maxRateDescription": "Very likely",
          "rateDescriptionLocation": "bottom"
        },
        {
          "type": "comment",
          "name": "improvements-required",
          "title": "What can we do to make your experience more satisfying?",
          "maxLength": 300
        },
        {
          "type": "checkbox",
          "name": "promoter-features",
          "title": "Which of the following features do you value the most?",
          "description": "Please select no more than three features.",
          "isRequired": true,
          "choices": [
            {
              "value": "performance",
              "text": "Performance"
            },
            {
              "value": "stability",
              "text": "Stability"
            },
            {
              "value": "ui",
              "text": "User interface"
            },
            {
              "value": "complete-functionality",
              "text": "Complete functionality"
            },
            {
              "value": "learning-materials",
              "text": "Learning materials (documentation, demos, code examples)"
            },
            {
              "value": "support",
              "text": "Quality support"
            }
          ],
          "showOtherItem": true,
          "otherPlaceholder": "Please specify...",
          "otherText": "Other features",
          "colCount": 2,
          "maxSelectedChoices": 3
        },
        {
          "type": "boolean",
          "name": "rebuy",
          "title": "Would you buy our product again?"
        }
      ]
    },
    {
      "name": "page3",
      "elements": [
        {
          "type": "radiogroup",
          "name": "testimonial",
          "title": "Would you mind providing us a brief testimonial for the website?",
          "choices": [
            {
              "value": "yes",
              "text": "Sure!"
            },
            {
              "value": "no",
              "text": "No"
            }
          ]
        },
        {
          "type": "text",
          "name": "email",
          "title": "What is your email address?",
          "validators": [
            {
              "type": "email"
            }
          ],
          "placeholder": "Enter your email here"
        }
      ]
    }
  ],
  "showPrevButton": false,
  "widthMode": "static",
  "width": "1000px"
};
```

### `src/SurveyCreatorComponent.jsx`

```js
import React from "react";
import { SurveyCreator, SurveyCreatorComponent } from "survey-creator-react";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
import { Serializer, Action, ComputedUpdater } from "survey-core";
import { SurveyPDF } from "survey-pdf";
import { getLocaleStrings } from "survey-creator-core";
import { formJSON } from "./survey_json";
import "survey-core/survey-core.css";
import "survey-creator-core/survey-creator-core.css";
import "./index.css";

import SurveyTheme from "survey-core/themes";
import { registerCreatorTheme } from "survey-creator-core";

registerCreatorTheme(SurveyTheme); // Add predefined Survey Creator UI themes

// Add PDF Generator settings to the Property Grid
const pdfCategoryName = "pdf";
const enStrings = getLocaleStrings("en");
enStrings.pe.tabs[pdfCategoryName] = "Export to PDF";

Serializer.addProperty("survey", {
    name: "pdfOrientation:buttongroup",
    displayName: "Page orientation",
    category: pdfCategoryName,
    categoryIndex: 800,
    default: "auto",
    choices: [ "auto", "p|Portrait", "l|Landscape" ],
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfFormat",
    displayName: "Page format",
    category: pdfCategoryName,
    default: "default",
    choices: [
        "default|Default", "custom|Custom", "a0|A0", "a1|A1", "a2|A2", "a3|A3", "a4|A4", "a5|A5", "a6|A6", "a7|A7",
        "a8|A8", "a9|A9", "a10|A10", "b0|B0", "b1|B1", "b2|B2", "b3|B3", "b4|B4", "b5|B5", "b6|B6", "b7|B7",
        "b8|B8", "b9|B9", "b10|B10", "c0|C0", "c1|C1", "c2|C2", "c3|C3", "c4|C4", "c5|C5", "c6|C6", "c7|C7",
        "c8|C8", "c9|C9", "c10|C10", "dl|DL", "letter|Letter", "government-letter|Government Letter", "legal|Legal",
        "junior-legal|Junior Legal", "ledger|Ledger", "tabloid|Tabloid", "credit-card|Credit Card"
    ],
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfPageWidth:number",
    displayName: "Page width",
    category: pdfCategoryName,
    default: 210.0,
    dependsOn: "pdfFormat",
    visibleIf: (obj) => obj.pdfFormat === "custom",
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfPageHeight:number",
    displayName: "Page height",
    category: pdfCategoryName,
    default: 297.0,
    dependsOn: "pdfFormat",
    visibleIf: (obj) => obj.pdfFormat === "custom",
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfFontName:buttongroup",
    displayName: "Font name",
    category: pdfCategoryName,
    default: "Helvetica",
    choices: [ "Helvetica", "Courier", "Times" ],
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfFontSize:number",
    displayName: "Font size",
    category: pdfCategoryName,
    default: 14,
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfMarginTop:number",
    displayName: "Top margin",
    category: pdfCategoryName,
    default: 10.0,
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfMarginBottom:number",
    displayName: "Bottom margin",
    category: pdfCategoryName,
    default: 10.0,
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfMarginLeft:number",
    displayName: "Left margin",
    category: pdfCategoryName,
    default: 10.0,
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfMarginRight:number",
    displayName: "Right margin",
    category: pdfCategoryName,
    default: 10.0,
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfReadonly:buttongroup",
    displayName: "Generate a read-only PDF document",
    category: pdfCategoryName,
    default: false,
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfHtmlRenderAs:buttongroup",
    displayName: "Render mode for HTML questions",
    category: pdfCategoryName,
    default: "auto",
    choices: [ "auto", "standard|Standard", "image|Image" ],
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfMatrixRenderAs:buttongroup",
    displayName: "Render mode for matrices",
    category: pdfCategoryName,
    default: "auto",
    choices: [ "auto", "list|List" ],
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfReadonlyRenderAs:buttongroup",
    displayName: "Render mode for read-only questions",
    category: pdfCategoryName,
    default: "auto",
    choices: ["auto", "acroform|AcroForms", "text|Plain text" ],
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfCompress:boolean",
    displayName: "Compress the PDF document",
    category: pdfCategoryName,
    default: false,
    isSerializable: false
});

Serializer.addProperty("survey", {
    name: "pdfFileName:string",
    displayName: "File name",
    category: pdfCategoryName,
    default: "survey.pdf",
    isSerializable: false
});

Serializer.addProperty("question", {
    name: "pdfIsPageBreak:boolean",
    displayName: "Insert a page break before this element",
    category: pdfCategoryName,
    categoryIndex: 800,
    default: false,
    isSerializable: false
});

function savePdf (survey) {
    const pdfDocOptions = {
        fontSize: survey.pdfFontSize,
        fontName: survey.pdfFontName,
        margins: {
            left: survey.pdfMarginLeft,
            right: survey.pdfMarginRight,
            top: survey.pdfMarginTop,
            bot: survey.pdfMarginBottom
        },
        htmlRenderAs: survey.pdfHtmlRenderAs,
        matrixRenderAs: survey.pdfMatrixRenderAs,
        readonlyRenderAs: survey.pdfReadonlyRenderAs,
        compress: survey.pdfCompress
    };
    if (survey.pdfOrientation !== "auto") {
        pdfDocOptions.orientation = survey.pdfOrientation;
    }
    if (survey.pdfFormat === "custom") {
        pdfDocOptions.format = [survey.pdfFormatWidth, survey.pdfFormatHeight]
    }
    else if (survey.pdfFormat !== "default") {
        pdfDocOptions.format = survey.pdfFormat;
    }
    const surveyPDF = new SurveyPDF(survey.toJSON(), pdfDocOptions);
    surveyPDF.readOnly = survey.pdfReadonly;
    surveyPDF.onRenderQuestion.add((_, options) => {
        options.bricks[0].isPageBreak = options.question.pdfIsPageBreak;
    });
    surveyPDF.save(survey.pdfFileName);
};

function SurveyCreatorRenderComponent() {
    const creator = new SurveyCreator();
    // Configure a custom toolbar button
    const savePdfAction = new Action({
        id: "svd-save-pdf",
        title: "Download PDF",
        visible: new ComputedUpdater(() => creator.activeTab === "designer"),
        enabled: true,
        action: () => {
            savePdf(creator.survey);
        }
    });
    
    // Add the button to the top toolbar
    creator.toolbar.actions.push(savePdfAction);
    
    // Add the button to the bottom toolbar (visible only on mobile devices)
    creator.footerToolbar.actions.push(savePdfAction);
    
    creator.JSON = formJSON;
    return (<SurveyCreatorComponent creator={creator} />);
}

export default SurveyCreatorRenderComponent;
```

### `src/index.css`

```css
/* You can add your custom CSS here. */
```

### `src/index.js`

```js
import React from "react";
import { createRoot } from "react-dom/client";
import SurveyCreatorRenderComponent from "./SurveyCreatorComponent";

const root = createRoot(document.getElementById("surveyCreatorContainer"));
root.render(<SurveyCreatorRenderComponent />);
```

### `package.json`

```json
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "survey-pdf": "latest",
    "survey-core": "latest",
    "survey-react-ui": "latest",
    "survey-creator-core": "latest",
    "survey-creator-react": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/survey-creator/examples/integrate-pdf-generator/angular.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/integrate-pdf-generator/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/integrate-pdf-generator/jquery.md)
- [Vanilla JS](https://surveyjs.io/survey-creator/examples/integrate-pdf-generator/vanillajs.md)
