Progress Indicator (PDF) (Vue)

The sample demonstrates how to export FlexGrid content to PDF files asynchronously, display a progress indicator and cancel the export.

The progress argument of the PdfWebWorkerClient's exportGrid method is used to track the export progress, the web worker's terminate method is used to cancel the export.

Learn about FlexGrid | FlexGrid API Reference

This example uses Vue.

app.vue
index.html
data.js
workers/export-grid.js
Copy to CodeMine
<template> <div class="container-fluid"> <wj-flex-grid class="grid" :autoGenerateColumns=false :itemsSource="data" :initialized="gridInitialized"> <wj-flex-grid-column header="ID" binding="id"></wj-flex-grid-column> <wj-flex-grid-column header="Country" binding="country"></wj-flex-grid-column> <wj-flex-grid-column header="Product" binding="product"></wj-flex-grid-column> <wj-flex-grid-column header="Amount" binding="amount" format="c"></wj-flex-grid-column> <wj-flex-grid-column header="Pending" binding="amount2" format="c2"></wj-flex-grid-column> <wj-flex-grid-column header="Discount" binding="discount" format="p1"></wj-flex-grid-column> <wj-flex-grid-column header="Active" binding="active"></wj-flex-grid-column> </wj-flex-grid> <div class="row "> <div class="col-md-6 col-xs-12 well well-sm"> <wj-linear-gauge :isReadOnly=true :min=0 :max=100 :value=0 :showText="'Value'" :initialized="progressBarInitialized"> </wj-linear-gauge> <button class="btn btn-default" @click="exportPdf()">Export</button> <button class="btn btn-default" @click="cancel()">Cancel</button> </div> </div> </div> </template> <script setup> import * as pdf from "@mescius/wijmo.pdf"; import * as gridPdf from "@mescius/wijmo.grid.pdf"; import { getData } from "./data"; import { ref } from "vue"; const data = ref(getData(3000)); const worker = ref(null); const flexGrid = ref(null); const progressBar = ref(null); function gridInitialized(ctl) { flexGrid.value = ctl; } function progressBarInitialized(ctl) { progressBar.value = ctl; } function exportPdf() { cancel(); // worker.value = loadWorker("./export-grid.js", () => { gridPdf.PdfWebWorkerClient.exportGrid( worker.value, flexGrid.value, "FlexGrid.pdf", { scaleMode: gridPdf.ScaleMode.PageWidth, styles: { cellStyle: { backgroundColor: "#ffffff", borderColor: "#c6c6c6", }, altCellStyle: { backgroundColor: "#f9f9f9", }, groupCellStyle: { backgroundColor: "#dddddd", }, headerCellStyle: { backgroundColor: "#eaeaea", }, }, }, null, (progress) => (progressBar.value.value = progress * 100), ); }); } function cancel() { if (worker.value) { worker.value.terminate(); } progressBar.value.value = 0; } // // Creates web worker that executes the module from the specified URL. function loadWorker(url, ready) { let worker = new Worker("src/workers/worker-loader.js"); // worker.addEventListener("message", (e) => { if (e.data === "#ready#") { ready(); } }); // worker.postMessage({ url: url }); // return worker; } </script> <style> .wj-flexgrid { height: 400px; margin: 6px 0; } .wj-gauge { margin: 20px auto; } </style>
<template> <div class="container-fluid"> <wj-flex-grid class="grid" :autoGenerateColumns=false :itemsSource="data" :initialized="gridInitialized"> <wj-flex-grid-column header="ID" binding="id"></wj-flex-grid-column> <wj-flex-grid-column header="Country" binding="country"></wj-flex-grid-column> <wj-flex-grid-column header="Product" binding="product"></wj-flex-grid-column> <wj-flex-grid-column header="Amount" binding="amount" format="c"></wj-flex-grid-column> <wj-flex-grid-column header="Pending" binding="amount2" format="c2"></wj-flex-grid-column> <wj-flex-grid-column header="Discount" binding="discount" format="p1"></wj-flex-grid-column> <wj-flex-grid-column header="Active" binding="active"></wj-flex-grid-column> </wj-flex-grid> <div class="row "> <div class="col-md-6 col-xs-12 well well-sm"> <wj-linear-gauge :isReadOnly=true :min=0 :max=100 :value=0 :showText="'Value'" :initialized="progressBarInitialized"> </wj-linear-gauge> <button class="btn btn-default" @click="exportPdf()">Export</button> <button class="btn btn-default" @click="cancel()">Cancel</button> </div> </div> </div> </template> <script setup> import * as pdf from "@mescius/wijmo.pdf"; import * as gridPdf from "@mescius/wijmo.grid.pdf"; import { getData } from "./data"; import { ref } from "vue"; const data = ref(getData(3000)); const worker = ref(null); const flexGrid = ref(null); const progressBar = ref(null); function gridInitialized(ctl) { flexGrid.value = ctl; } function progressBarInitialized(ctl) { progressBar.value = ctl; } function exportPdf() { cancel(); // worker.value = loadWorker("./export-grid.js", () => { gridPdf.PdfWebWorkerClient.exportGrid( worker.value, flexGrid.value, "FlexGrid.pdf", { scaleMode: gridPdf.ScaleMode.PageWidth, styles: { cellStyle: { backgroundColor: "#ffffff", borderColor: "#c6c6c6", }, altCellStyle: { backgroundColor: "#f9f9f9", }, groupCellStyle: { backgroundColor: "#dddddd", }, headerCellStyle: { backgroundColor: "#eaeaea", }, }, }, null, (progress) => (progressBar.value.value = progress * 100), ); }); } function cancel() { if (worker.value) { worker.value.terminate(); } progressBar.value.value = 0; } // // Creates web worker that executes the module from the specified URL. function loadWorker(url, ready) { let worker = new Worker("src/workers/worker-loader.js"); // worker.addEventListener("message", (e) => { if (e.data === "#ready#") { ready(); } }); // worker.postMessage({ url: url }); // return worker; } </script> <style> .wj-flexgrid { height: 400px; margin: 6px 0; } .wj-gauge { margin: 20px auto; } </style>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Progress Indicator</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="compiler.js" type="module"></script> <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.js'); </script> </head> <body> <div id="app"> </div> </body> </html>
export function getData(count) { let countries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'], products = ['Widget', 'Gadget', 'Doohickey'], data = []; // for (let i = 0; i < count; i++) { let countryId = Math.floor(Math.random() * countries.length), productId = Math.floor(Math.random() * products.length); // let item = { id: i, country: countries[countryId], product: products[productId], amount: Math.random() * 10000, amount2: Math.random() * 10000, discount: Math.random() / 4, active: i % 4 == 0 }; // data.push(item); } // return data; }
import { PdfWebWorker } from '@mescius/wijmo.grid.pdf'; // PdfWebWorker.initExportGrid();
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' }, '*.vue': { loader: '../plugin-vue/index.js' } //'*.vue': { loader: 'systemjs-plugin-vue' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@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', "@mescius/wijmo.vue2.chart.analytics": "npm:@mescius/wijmo.vue2.chart.analytics/index.js", "@mescius/wijmo.vue2.chart.animation": "npm:@mescius/wijmo.vue2.chart.animation/index.js", "@mescius/wijmo.vue2.chart.annotation": "npm:@mescius/wijmo.vue2.chart.annotation/index.js", "@mescius/wijmo.vue2.chart.finance.analytics": "npm:@mescius/wijmo.vue2.chart.finance.analytics/index.js", "@mescius/wijmo.vue2.chart.finance": "npm:@mescius/wijmo.vue2.chart.finance/index.js", "@mescius/wijmo.vue2.chart.hierarchical": "npm:@mescius/wijmo.vue2.chart.hierarchical/index.js", "@mescius/wijmo.vue2.chart.interaction": "npm:@mescius/wijmo.vue2.chart.interaction/index.js", "@mescius/wijmo.vue2.chart.radar": "npm:@mescius/wijmo.vue2.chart.radar/index.js", '@mescius/wijmo.vue2.chart.map': 'npm:@mescius/wijmo.vue2.chart.map/index.js', "@mescius/wijmo.vue2.chart": "npm:@mescius/wijmo.vue2.chart/index.js", "@mescius/wijmo.vue2.core": "npm:@mescius/wijmo.vue2.core/index.js", "@mescius/wijmo.vue2.gauge": "npm:@mescius/wijmo.vue2.gauge/index.js", "@mescius/wijmo.vue2.grid.detail": "npm:@mescius/wijmo.vue2.grid.detail/index.js", "@mescius/wijmo.vue2.grid.filter": "npm:@mescius/wijmo.vue2.grid.filter/index.js", "@mescius/wijmo.vue2.grid.grouppanel": "npm:@mescius/wijmo.vue2.grid.grouppanel/index.js", '@mescius/wijmo.vue2.grid.search': 'npm:@mescius/wijmo.vue2.grid.search/index.js', "@mescius/wijmo.vue2.grid.multirow": "npm:@mescius/wijmo.vue2.grid.multirow/index.js", "@mescius/wijmo.vue2.grid.sheet": "npm:@mescius/wijmo.vue2.grid.sheet/index.js", '@mescius/wijmo.vue2.grid.transposed': 'npm:@mescius/wijmo.vue2.grid.transposed/index.js', '@mescius/wijmo.vue2.grid.transposedmultirow': 'npm:@mescius/wijmo.vue2.grid.transposedmultirow/index.js', "@mescius/wijmo.vue2.grid": "npm:@mescius/wijmo.vue2.grid/index.js", "@mescius/wijmo.vue2.input": "npm:@mescius/wijmo.vue2.input/index.js", "@mescius/wijmo.vue2.olap": "npm:@mescius/wijmo.vue2.olap/index.js", "@mescius/wijmo.vue2.viewer": "npm:@mescius/wijmo.vue2.viewer/index.js", "@mescius/wijmo.vue2.nav": "npm:@mescius/wijmo.vue2.nav/index.js", "@mescius/wijmo.vue2.base": "npm:@mescius/wijmo.vue2.base/index.js", '@mescius/wijmo.vue2.barcode.common': 'npm:@mescius/wijmo.vue2.barcode.common/index.js', '@mescius/wijmo.vue2.barcode.composite': 'npm:@mescius/wijmo.vue2.barcode.composite/index.js', '@mescius/wijmo.vue2.barcode.specialized': 'npm:@mescius/wijmo.vue2.barcode.specialized/index.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'jszip': 'npm:jszip/dist/jszip.js', 'css': 'npm:systemjs-plugin-css/css.js', 'vue': 'npm:vue/dist/vue.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', 'vue-loader': 'npm:systemjs-vue-browser/index.js', //'systemjs-plugin-vue': 'npm:systemjs-plugin-vue/index.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' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, wijmo: { defaultExtension: 'js', } } }); })(this);