UNPKG

survey-pdf

Version:

A UI component that uses SurveyJS form JSON schemas to render forms as PDF documents. It populates PDF fields with data collected using SurveyJS Form Library and lets you export your SurveyJS forms as editable or pre-filled PDFs.

341 lines (324 loc) 16.8 kB
/*! * surveyjs - SurveyJS PDF library v2.5.20 * Copyright (c) 2015-2026 Devsoft Baltic OÜ - http://surveyjs.io/ * License: MIT (http://www.opensource.org/licenses/mit-license.php) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('fs')) : typeof define === 'function' && define.amd ? define(['exports', 'fs'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.PDFFormFiller = {}, global.fs)); })(this, (function (exports, fs) { 'use strict'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var FormsMap = /** @class */ (function () { function FormsMap(map) { this.map = map; this.res = {}; } FormsMap.prototype.mapDataRecursive = function (data, map) { var _this = this; if (data === undefined || data === null) return; if (typeof (data) !== 'object') { if (Array.isArray(map)) { map.forEach(function (m) { _this.mapDataRecursive(data, m); }); return; } if (typeof (map) !== 'object') { this.res[map] = data; } else { this.res[map[data].field] = map[data].value; } return; } if (Array.isArray(data)) { data.forEach(function (d, i) { _this.mapDataRecursive(d, Array.isArray(map) ? map[i] : map); }); return; } Object.keys(data).forEach(function (key) { _this.mapDataRecursive(data[key], map[key]); }); }; FormsMap.prototype.mapData = function (data) { this.res = {}; this.mapDataRecursive(data, this.map); return this.res; }; return FormsMap; }()); /** * A base class for the `PDFFormFiller` plugin. */ var PDFFormFillerBase = /** @class */ (function () { function PDFFormFillerBase(options) { if (options) { this.data = options.data; this.fieldMap = options.fieldMap; this.pdfTemplate = options.pdfTemplate; this.pdfLibraryAdapter = options.pdfLibraryAdapter; } } PDFFormFillerBase.prototype.getPDFBytes = function () { return __awaiter(this, void 0, void 0, function () { var map, plainData; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: map = new FormsMap(this.fieldMap); plainData = map.mapData(this.data); return [4 /*yield*/, ((_a = this.pdfLibraryAdapter) === null || _a === void 0 ? void 0 : _a.fillForm(this.pdfTemplate, plainData))]; case 1: return [2 /*return*/, _b.sent()]; } }); }); }; PDFFormFillerBase.prototype.fromCharCode = function (array) { var strings = []; var chunkSize = 0xffff; for (var i = 0; i < array.length; i += chunkSize) { var chunk = Array.prototype.slice.call(array, i, i + chunkSize); strings.push(String.fromCharCode.apply(null, chunk)); } return strings.join(''); }; /** * An asynchronous method that allows you to get PDF content in different formats. * @param type *(Optional)* One of `"blob"`, `"bloburl"`, `"dataurlstring"`. Do not specify this parameter if you want to get raw PDF content as a string value. */ PDFFormFillerBase.prototype.raw = function (type) { return __awaiter(this, void 0, void 0, function () { var pdfBytes, blob; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getPDFBytes()]; case 1: pdfBytes = _a.sent(); if (!type || !pdfBytes) return [2 /*return*/, pdfBytes]; if (type == 'dataurlstring') return [2 /*return*/, 'data:application/pdf;base64,' + btoa(this.fromCharCode(pdfBytes))]; blob = new Blob([pdfBytes], { type: 'application/pdf' }); if (type == 'blob') return [2 /*return*/, blob]; if (type == 'bloburl') return [2 /*return*/, URL.createObjectURL(blob)]; return [2 /*return*/, pdfBytes]; } }); }); }; /** * An asynchronous method that starts to download the filled PDF form in the web browser. * * [View pdf-lib Demo](https://surveyjs.io/pdf-generator/examples/map-survey-responses-to-pdf-fields-using-pdflib/ (linkStyle)) * * [View PDF.js Demo](https://surveyjs.io/pdf-generator/examples/fill-in-pdf-form-fields-with-dynamic-survey-data-using-pdfjs/ (linkStyle)) * @param fileName *(Optional)* A file name with the ".pdf" extension. Default value: `"FilledForm.pdf"`. */ PDFFormFillerBase.prototype.save = function () { return __awaiter(this, arguments, void 0, function (fileName) { var pdfBytes; if (fileName === void 0) { fileName = 'FilledForm.pdf'; } return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getPDFBytes()]; case 1: pdfBytes = _a.sent(); if (!pdfBytes) return [2 /*return*/]; return [4 /*yield*/, this.saveToFile(pdfBytes, fileName)]; case 2: _a.sent(); return [2 /*return*/]; } }); }); }; return PDFFormFillerBase; }()); var PDFFormFiller = /** @class */ (function (_super) { __extends(PDFFormFiller, _super); function PDFFormFiller() { return _super !== null && _super.apply(this, arguments) || this; } PDFFormFiller.prototype.saveToFile = function (pdfBytes, fileName) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (resolve, reject) { fs.writeFile(fileName, pdfBytes, function (err) { if (err) reject(err); else resolve(); }); })]; }); }); }; return PDFFormFiller; }(PDFFormFillerBase)); var PDFLibAdapter = /** @class */ (function () { function PDFLibAdapter(pdfLibrary) { this.pdfLibrary = pdfLibrary; } PDFLibAdapter.prototype.fillForm = function (template, data) { return __awaiter(this, void 0, void 0, function () { var _a, PDFDocument, PDFTextField, PDFCheckBox, PDFRadioGroup, PDFDropdown, pdfDoc, form, fields; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.pdfLibrary, PDFDocument = _a.PDFDocument, PDFTextField = _a.PDFTextField, PDFCheckBox = _a.PDFCheckBox, PDFRadioGroup = _a.PDFRadioGroup, PDFDropdown = _a.PDFDropdown; return [4 /*yield*/, PDFDocument.load(template)]; case 1: pdfDoc = _b.sent(); form = pdfDoc.getForm(); fields = form.getFields(); fields.forEach(function (field) { var fieldName = field.getName(); var value = data[fieldName]; if (value === null || value === undefined) return; if (field instanceof PDFTextField) { field.setText(value); } else if (field instanceof PDFCheckBox) { if (value) field.check(); else field.uncheck(); } else if (field instanceof PDFRadioGroup || field instanceof PDFDropdown) { field.select(value.toString()); } }); return [4 /*yield*/, pdfDoc.save()]; case 2: return [2 /*return*/, _b.sent()]; } }); }); }; return PDFLibAdapter; }()); var PDFJSAdapter = /** @class */ (function () { function PDFJSAdapter(pdfLibrary) { this.pdfLibrary = pdfLibrary; } PDFJSAdapter.prototype.fillForm = function (template, data) { return __awaiter(this, void 0, void 0, function () { var pdfjsLib, doc, numPages, pageNum, page, annotations; return __generator(this, function (_a) { switch (_a.label) { case 0: pdfjsLib = this.pdfLibrary; return [4 /*yield*/, pdfjsLib.getDocument(template).promise]; case 1: doc = _a.sent(); numPages = doc.numPages; pageNum = 1; _a.label = 2; case 2: if (!(pageNum <= numPages)) return [3 /*break*/, 6]; return [4 /*yield*/, doc.getPage(pageNum)]; case 3: page = _a.sent(); return [4 /*yield*/, page.getAnnotations()]; case 4: annotations = _a.sent(); annotations.forEach(function (field) { if (field.fieldType == undefined) return; var value = data[field.fieldName]; if (value) { if (field.radioButton && field.buttonValue != value) { return; } doc.annotationStorage.setValue(field.id, { value: value }); } }); _a.label = 5; case 5: pageNum++; return [3 /*break*/, 2]; case 6: return [4 /*yield*/, doc.saveDocument()]; case 7: return [2 /*return*/, _a.sent()]; } }); }); }; return PDFJSAdapter; }()); exports.PDFFormFiller = PDFFormFiller; exports.PDFJSAdapter = PDFJSAdapter; exports.PDFLibAdapter = PDFLibAdapter; })); //# sourceMappingURL=pdf-form-filler.node.js.map