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.
210 lines (198 loc) • 8.27 kB
JavaScript
/*!
* surveyjs - SurveyJS PDF library v2.5.34
* Copyright (c) 2015-2026 Devsoft Baltic OÜ - http://surveyjs.io/
* License: MIT (http://www.opensource.org/licenses/mit-license.php)
*/
/******************************************************************************
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 */
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());
});
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
class FormsMap {
constructor(map) {
this.map = map;
this.res = {};
}
mapDataRecursive(data, map) {
if (data === undefined || data === null)
return;
if (typeof (data) !== 'object') {
if (Array.isArray(map)) {
map.forEach((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((d, i) => {
this.mapDataRecursive(d, Array.isArray(map) ? map[i] : map);
});
return;
}
Object.keys(data).forEach(key => {
this.mapDataRecursive(data[key], map[key]);
});
}
mapData(data) {
this.res = {};
this.mapDataRecursive(data, this.map);
return this.res;
}
}
/**
* A base class for the `PDFFormFiller` plugin.
*/
class PDFFormFillerBase {
constructor(options) {
if (options) {
this.data = options.data;
this.fieldMap = options.fieldMap;
this.pdfTemplate = options.pdfTemplate;
this.pdfLibraryAdapter = options.pdfLibraryAdapter;
}
}
getPDFBytes() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const map = new FormsMap(this.fieldMap);
const plainData = map.mapData(this.data);
return yield ((_a = this.pdfLibraryAdapter) === null || _a === void 0 ? void 0 : _a.fillForm(this.pdfTemplate, plainData));
});
}
fromCharCode(array) {
const strings = [];
const chunkSize = 0xffff;
for (let i = 0; i < array.length; i += chunkSize) {
const 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.
*/
raw(type) {
return __awaiter(this, void 0, void 0, function* () {
const pdfBytes = yield this.getPDFBytes();
if (!type || !pdfBytes)
return pdfBytes;
if (type == 'dataurlstring')
return 'data:application/pdf;base64,' + btoa(this.fromCharCode(pdfBytes));
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
if (type == 'blob')
return blob;
if (type == 'bloburl')
return URL.createObjectURL(blob);
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"`.
*/
save() {
return __awaiter(this, arguments, void 0, function* (fileName = 'FilledForm.pdf') {
const pdfBytes = yield this.getPDFBytes();
if (!pdfBytes)
return;
yield this.saveToFile(pdfBytes, fileName);
});
}
}
class PDFLibAdapter {
constructor(pdfLibrary) {
this.pdfLibrary = pdfLibrary;
}
fillForm(template, data) {
return __awaiter(this, void 0, void 0, function* () {
const { PDFDocument, PDFTextField, PDFCheckBox, PDFRadioGroup, PDFDropdown } = this.pdfLibrary;
const pdfDoc = yield PDFDocument.load(template);
const form = pdfDoc.getForm();
const fields = form.getFields();
fields.forEach((field) => {
const fieldName = field.getName();
const 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 yield pdfDoc.save();
});
}
}
class PDFJSAdapter {
constructor(pdfLibrary) {
this.pdfLibrary = pdfLibrary;
}
fillForm(template, data) {
return __awaiter(this, void 0, void 0, function* () {
const pdfjsLib = this.pdfLibrary;
const doc = yield pdfjsLib.getDocument(template).promise;
const numPages = doc.numPages;
// Process all pages
for (let pageNum = 1; pageNum <= numPages; pageNum++) {
const page = yield doc.getPage(pageNum);
const annotations = yield page.getAnnotations();
annotations.forEach((field) => {
if (field.fieldType == undefined)
return;
const value = data[field.fieldName];
if (value) {
if (field.radioButton && field.buttonValue != value) {
return;
}
doc.annotationStorage.setValue(field.id, { value });
}
});
}
return yield doc.saveDocument();
});
}
}
export { PDFFormFillerBase as P, __awaiter as _, PDFJSAdapter as a, PDFLibAdapter as b };
//# sourceMappingURL=pdf-form-filler-shared.mjs.map