Security

The sample demonstrates how to export FlexGrid content to password-protected PDF file and how to set PDF file permissions.

The sample uses wijmo.pdf.security module to enhance wijmo.pdf with security capabilities.

The IFlexGridExportSettings' documentOptions property is used to provide security settings, such as userPassword and permissions, to the underlying PdfDocument.

Learn about FlexGrid | FlexGrid API Reference

import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; // import * as input from '@mescius/wijmo.input'; import * as grid from '@mescius/wijmo.grid'; import * as gridPdf from '@mescius/wijmo.grid.pdf'; import '@mescius/wijmo.pdf.security'; // import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { let menuVersion = new input.Menu('#menuVersion', { selectedIndexChanged: (s) => { if (s.selectedIndex >= 0) { updateMenuHeader(s, 'PDF version'); } } }); updateMenuHeader(menuVersion, 'PDF version'); // let flexGrid = new grid.FlexGrid('#flexGrid', { autoGenerateColumns: false, selectionMode: grid.SelectionMode.ListBox, headersVisibility: grid.HeadersVisibility.All, columns: [ { header: 'ID', binding: 'id' }, { header: 'Start Date', binding: 'start', format: 'd' }, { header: 'End Date', binding: 'end', format: 'd' }, { header: 'Country', binding: 'country' } ], itemsSource: getData(10) }); // document.querySelector('#btnExport').addEventListener('click', () => { let settings = { documentOptions: { userPassword: document.querySelector('#tbUserPassword').value, ownerPassword: document.querySelector('#tbOwnerPassword').value, version: menuVersion.selectedValue, permissions: { annotating: document.querySelector('#cbAnnotating').checked, contentAccessibility: document.querySelector('#cbContentAccessibility').checked, copying: document.querySelector('#cbCopying').checked, documentAssembly: document.querySelector('#cbDocumentAssembly').checked, fillingForms: document.querySelector('#cbFillingForms').checked, modifying: document.querySelector('#cbModifying').checked, printing: document.querySelector('input[name="printing"]:checked').value } }, styles: { cellStyle: { backgroundColor: '#ffffff', borderColor: '#c6c6c6' }, altCellStyle: { backgroundColor: '#f9f9f9' }, groupCellStyle: { backgroundColor: '#dddddd' }, headerCellStyle: { backgroundColor: '#eaeaea' } } }; // gridPdf.FlexGridPdfConverter.export(flexGrid, 'FlexGrid.pdf', settings); }); } // function updateMenuHeader(menu, header) { menu.header = header + ': <b>' + menu.text + '</b>'; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Security</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.5/system.src.js" integrity="sha512-skZbMyvYdNoZfLmiGn5ii6KmklM82rYX2uWctBhzaXPxJgiv4XBwJnFGr5k8s+6tE1pcR1nuTKghozJHyzMcoA==" crossorigin="anonymous"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <div class="panel panel-default"> <div class="panel-heading"> Security settings </div> <div class="panel-body"> <div class="row"> <div class="col-sm-3"> <input type="text" id="tbUserPassword" class="form-control" placeholder="User password" /> </div> <div class="col-sm-3"> <input type="text" id="tbOwnerPassword" class="form-control" placeholder="Owner password" /> </div> </div> <hr /> <div class="row"> <div class="col-sm-3"> <select id="menuVersion" class="form-control"> <option value="v1_3" selected>1.3</option> <option value="v1_4">1.4</option> <option value="v1_5">1.5</option> <option value="v1_6">1.6</option> <option value="v1_7">1.7</option> <option value="v1_7Ext3">1.7 ExtensionLevel 3</option> </select> </div> </div> <hr /> <div class="row"> <div class="col"> <b>Permissions</b> (require owner password) </div> </div> <div class="row"> <div class="col-sm-3"> <div class="checkbox"> <label> <input type="checkbox" id="cbAnnotating" />Annotating </label> </div> <div class="checkbox"> <label> <input type="checkbox" id="cbContentAccessibility" />ContentAccessibility </label> </div> <div class="checkbox"> <label> <input type="checkbox" id="cbCopying" />Copying </label> </div> <div class="checkbox"> <label> <input type="checkbox" id="cbDocumentAssembly" />DocumentAssembly </label> </div> <div class="checkbox"> <label> <input type="checkbox" id="cbFillingForms" />FillingForms </label> </div> <div class="checkbox"> <label> <input type="checkbox" id="cbModifying" />Modifying </label> </div> </div> </div> <div class="row"> <div class="col-sm-2">Printing</div> </div> <div class="row"> <div class="col-sm-6"> <label class="radio-inline"> <input name="printing" id="cbPrintingNotSet" value="NotAllowed" type="radio" checked />NotAllowed </label> <label class="radio-inline"> <input name="printing" id="cbPrintingLowRes" value="AllowLowResolution" type="radio" />AllowLowResolution </label> <label class="radio-inline"> <input name="printing" id="cbPrintingHiRes" value="AllowHighResolution" type="radio" />AllowHighResolution </label> </div> </div> </div> </div> <!-- Export button --> <button class="btn btn-default" id="btnExport">Export</button> <!-- FlexGrid --> <div id="flexGrid" class="grid"></div> </div> </body> </html>
export function getData(count) { // data used to generate random items const countries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece']; // let data = []; let dt = new Date(); // // add count items for (let i = 0; i < count; i++) { // constants used to create data items let date = new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60), countryId = Math.floor(Math.random() * countries.length); // // create the item let item = { id: i, start: date, end: date, country: countries[countryId] }; // // add the item to the list data.push(item); } // return data; }
body { margin-bottom: 24px; } .grid { margin-top: 20px; height: 300px; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'jszip': 'npm:jszip/dist/jszip.js', '@mescius/wijmo': 'npm:@mescius/wijmo/index.js', '@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js', '@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles', '@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures', '@mescius/wijmo.chart': 'npm:@mescius/wijmo.chart/index.js', '@mescius/wijmo.chart.analytics': 'npm:@mescius/wijmo.chart.analytics/index.js', '@mescius/wijmo.chart.animation': 'npm:@mescius/wijmo.chart.animation/index.js', '@mescius/wijmo.chart.annotation': 'npm:@mescius/wijmo.chart.annotation/index.js', '@mescius/wijmo.chart.finance': 'npm:@mescius/wijmo.chart.finance/index.js', '@mescius/wijmo.chart.finance.analytics': 'npm:@mescius/wijmo.chart.finance.analytics/index.js', '@mescius/wijmo.chart.hierarchical': 'npm:@mescius/wijmo.chart.hierarchical/index.js', '@mescius/wijmo.chart.interaction': 'npm:@mescius/wijmo.chart.interaction/index.js', '@mescius/wijmo.chart.radar': 'npm:@mescius/wijmo.chart.radar/index.js', '@mescius/wijmo.chart.render': 'npm:@mescius/wijmo.chart.render/index.js', '@mescius/wijmo.chart.webgl': 'npm:@mescius/wijmo.chart.webgl/index.js', '@mescius/wijmo.chart.map': 'npm:@mescius/wijmo.chart.map/index.js', '@mescius/wijmo.gauge': 'npm:@mescius/wijmo.gauge/index.js', '@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js', '@mescius/wijmo.grid.detail': 'npm:@mescius/wijmo.grid.detail/index.js', '@mescius/wijmo.grid.filter': 'npm:@mescius/wijmo.grid.filter/index.js', '@mescius/wijmo.grid.search': 'npm:@mescius/wijmo.grid.search/index.js', '@mescius/wijmo.grid.style': 'npm:@mescius/wijmo.grid.style/index.js', '@mescius/wijmo.grid.grouppanel': 'npm:@mescius/wijmo.grid.grouppanel/index.js', '@mescius/wijmo.grid.multirow': 'npm:@mescius/wijmo.grid.multirow/index.js', '@mescius/wijmo.grid.transposed': 'npm:@mescius/wijmo.grid.transposed/index.js', '@mescius/wijmo.grid.transposedmultirow': 'npm:@mescius/wijmo.grid.transposedmultirow/index.js', '@mescius/wijmo.grid.pdf': 'npm:@mescius/wijmo.grid.pdf/index.js', '@mescius/wijmo.grid.sheet': 'npm:@mescius/wijmo.grid.sheet/index.js', '@mescius/wijmo.grid.xlsx': 'npm:@mescius/wijmo.grid.xlsx/index.js', '@mescius/wijmo.grid.selector': 'npm:@mescius/wijmo.grid.selector/index.js', '@mescius/wijmo.grid.cellmaker': 'npm:@mescius/wijmo.grid.cellmaker/index.js', '@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js', '@mescius/wijmo.odata': 'npm:@mescius/wijmo.odata/index.js', '@mescius/wijmo.olap': 'npm:@mescius/wijmo.olap/index.js', '@mescius/wijmo.rest': 'npm:@mescius/wijmo.rest/index.js', '@mescius/wijmo.pdf': 'npm:@mescius/wijmo.pdf/index.js', '@mescius/wijmo.pdf.security': 'npm:@mescius/wijmo.pdf.security/index.js', '@mescius/wijmo.viewer': 'npm:@mescius/wijmo.viewer/index.js', '@mescius/wijmo.xlsx': 'npm:@mescius/wijmo.xlsx/index.js', '@mescius/wijmo.undo': 'npm:@mescius/wijmo.undo/index.js', '@mescius/wijmo.interop.grid': 'npm:@mescius/wijmo.interop.grid/index.js', '@mescius/wijmo.touch': 'npm:@mescius/wijmo.touch/index.js', '@mescius/wijmo.cloud': 'npm:@mescius/wijmo.cloud/index.js', '@mescius/wijmo.barcode': 'npm:@mescius/wijmo.barcode/index.js', '@mescius/wijmo.barcode.common': 'npm:@mescius/wijmo.barcode.common/index.js', '@mescius/wijmo.barcode.composite': 'npm:@mescius/wijmo.barcode.composite/index.js', '@mescius/wijmo.barcode.specialized': 'npm:@mescius/wijmo.barcode.specialized/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);