IO

GanttSheet supports importing and exporting different kinds of file types, and it also supports printing and exporting to pdf.

Description
app.component.ts
index.html
app.component.html
styles.css
Copy to CodeMine

Required Dependency

If you want to support the IO feature (except json serialization/deserialization) you need to import the modules:

  • TableSheet: spread-sheets-tablesheet
  • GanttSheet: spread-sheets-ganttsheet
  • SJS IO: spread-sheets-io
  • Print: spread-sheets-print
  • PDF: spread-sheets-pdf

Export to Excel

If you want to export the gantt data to Excel, you need to make sure the serialization option is includeBindingSource: true.

Note: The gantt chart column will be exported as a picture in the Excel file.

Required Dependency If you want to support the IO feature (except json serialization/deserialization) you need to import the modules: TableSheet: spread-sheets-tablesheet GanttSheet: spread-sheets-ganttsheet SJS IO: spread-sheets-io Print: spread-sheets-print PDF: spread-sheets-pdf Export to Excel If you want to export the gantt data to Excel, you need to make sure the serialization option is includeBindingSource: true. Note: The gantt chart column will be exported as a picture in the Excel file.
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ import { Component, NgModule, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { SpreadSheetsModule } from '@mescius/spread-sheets-angular'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-print'; import '@mescius/spread-sheets-pdf'; import '@mescius/spread-sheets-io'; import "@mescius/spread-sheets-tablesheet"; import "@mescius/spread-sheets-ganttsheet"; import './styles.css'; declare var SplitView: any; declare var saveAs: any; var FileType = { SJS: 'sjs', Excel: 'xlsx', SSJson: 'ssjson' }; var openOptions = { openMode: GC.Spread.Sheets.OpenMode.normal, fullRecalc: true }; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { spread: GC.Spread.Sheets.Workbook; ganttSheet: GC.Spread.Sheets.GanttSheet; hostStyle = { width: '100%', height: '100%' }; initSpread($event: any) { this.spread = $event.spread; let spread = this.spread; spread.suspendPaint(); spread.clearSheets(); this.initDataSource(spread); this.initGanttSheet(spread); spread.resumePaint(); initSplitView(spread); } initDataSource(spread) { var tableName = "Gantt_Id"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); var myTable = dataManager.addTable("myTable", { batch: true, remote: { read: { url: apiUrl } }, schema: { hierarchy: { type: "Parent", column: "parentId" }, columns: { id: { isPrimaryKey: true }, taskNumber: { dataType: "rowOrder" } } } }); this.myTable = myTable; } initGanttSheet(spread) { var ganttSheet = spread.addSheetTab(0, "GanttSheet", GC.Spread.Sheets.SheetType.ganttSheet); var view = this.myTable.addView("ganttView", [ { value: "taskNumber", caption: "NO.", width: 60 }, { value: "name", caption: "Task Name", width: 200 }, { value: "duration", caption: "Duration", width: 90 }, { value: "predecessors", caption: "Predecessors", width: 120, visible: false } ]); view.fetch().then(function() { ganttSheet.bindGanttView(view); }); this.ganttSheet = ganttSheet; } uploadFile() { var fileInput = document.getElementById("file-input"); fileInput.click(); } openFile(e) { var spread = this.spread; var fileNameItem = document.getElementById("file-name"); var fileInput = document.getElementById("file-input"); fileNameItem.value = 'Loading file...'; var file = fileInput.files[0]; if (!file) { alert("Upload a file first."); return; } var fileType = getFileType(file); var fileName = file.name; if (fileType === FileType.SJS) { spread.open(file, function() { fileNameItem.value = fileName; fileInput.value = ''; }, function() {}, openOptions); } else { spread.import(file, function() { fileNameItem.value = fileName; fileInput.value = ''; }, function() {}, openOptions); } } exportFile(fileType) { var spread = this.spread; var fileName = 'export.' + fileType; var options = getExportOptions(fileType); if (fileType === FileType.SJS) { spread.save(function(blob) { saveAs(blob, fileName); }, function() {}, options); } else { spread.export(function(blob) { saveAs(blob, fileName); }, function() {}, options); } } printSpread() { this.spread.print(); } savePDF() { this.spread.savePDF( function (blob) { saveAs(blob, 'download.pdf'); }, function () {} ); } } function getFileType (file) { if (!file) { return; } var fileName = file.name; var extensionName = fileName.substring(fileName.lastIndexOf(".") + 1); if (extensionName === 'sjs') { return FileType.SJS; } else if (extensionName === 'xlsx' || extensionName === 'xlsm') { return FileType.Excel; } else if (extensionName === 'ssjson' || extensionName === 'json') { return FileType.SSJson; } } function getExportOptions(fileType) { return { fileType: GC.Spread.Sheets.FileType[fileType], includeBindingSource: true, saveAsView: true }; } function initSplitView(spread) { var host = document.getElementById("split-view"); var content = host.getElementsByClassName("split-content")[0]; var panel = host.getElementsByClassName("split-panel")[0]; new SplitView({ host: host, content: content, panel: panel, refreshContent: function() { spread.refresh(); } }); } function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; } @NgModule({ imports: [BrowserModule, SpreadSheetsModule], declarations: [AppComponent], exports: [AppComponent], bootstrap: [AppComponent] }) export class AppModule {} enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule);
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/angular/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/spread/source/splitView/splitView.css"> <!-- Polyfills --> <script src="$DEMOROOT$/en/angular/node_modules/core-js/client/shim.min.js"></script> <script src="$DEMOROOT$/en/angular/node_modules/zone.js/fesm2015/zone.min.js"></script> <!-- SystemJS --> <script src="$DEMOROOT$/en/angular/node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <!-- plugins --> <script src="$DEMOROOT$/spread/source/splitView/SplitView.js"></script> <script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.import('@angular/compiler'); System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('$DEMOROOT$/en/lib/angular/license.ts'); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html>
<div id="split-view" class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets split-content" [hostStyle]="hostStyle" (workbookInitialized)="initSpread($event)"></gc-spread-sheets> <div class="options-container split-panel"> <div class="option-block"> <input id="file-input" type="file" name="files[]" accept=".xlsx, .ssjson, .json, .sjs, .zip, .xlsm" class="hide" (change)="openFile()" /> <div class="option-row input-box"> <label for="file-name">File Name</label> <input type="text" id="file-name" value="" disabled /> </div> <div class="option-row"> <input type="button" id="open-file" class="option-button" value="Open File" (click)="uploadFile()" /> <div class="option-info">File Type: *.ssjson, *.sjs</div> </div> </div> <div class="option-block"> <div class="option-row"> <input type="button" id="export-to-json" class="option-button" value="Export to JSON" (click)="exportFile('ssjson')" /> </div> <div class="option-row"> <input type="button" id="export-to-sjs" class="option-button" value="Export to SJS" (click)="exportFile('sjs')" /> </div> <div class="option-row"> <input type="button" id="export-to-excel" class="option-button" value="Export to Excel" (click)="exportFile('xlsx')" /> </div> </div> <div class="option-block"> <div class="option-row"> <input type="button" id="print" class="option-button" value="Print" (click)="printSpread()" /> </div> <div class="option-row"> <input type="button" id="pdf" class="option-button" value="PDF" (click)="savePDF()" /> </div> </div> </div> </div>
.options-container { float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; box-shadow: inset 0px 0 4px 0 rgba(0,0,0,0.4); } .option-block { background: #fff; padding: 8px; margin: 12px 0; border-radius: 4px; border: 1px dashed #82bc00; box-shadow: 0px 0 6px 0 rgba(0,0,0,0.1); } .option-block.toggle { border: 1px dotted #f7a711; } .option-row { font-size: 14px; box-sizing: border-box; padding: 4px 0; } .option-title { font-weight: bold; color: #656565; } .option-info { font-size: 12px; color: #919191; margin-top: 6px; font-weight: normal; } .option-info.valid { color: #82bc00; } .option-info.toggle { color: #f7a711; } .option-button { width: 100%; padding: 0; line-height: 20px; background: #82bc00; color: #fff; transition: 0.3s; cursor: pointer; outline: none; border-radius: 4px; box-sizing: border-box; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); border: none; } .option-button:hover { background: #82bc00; color: #fff; box-shadow: 0 3px 8px 0 rgba(0,0,0,0.4); } .option-checkbox { background: #fff; border: 1px dashed #f7a711; color: #f7a711; padding: 2px 4px; transition: 0.3s; box-sizing: border-box; cursor: pointer; } .option-checkbox.active { color: #fff; background: #f7a711; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); border-radius: 4px; } .selection-box { position: relative; } .selection-box > select { text-align: left; width: 100%; height: 20px; padding: 0; line-height: 20px; background: transparent; border: none; border-bottom: 2px solid #656565; color: #656565; transition: 0.3s; cursor: pointer; outline: none; box-sizing: border-box; } .selection-box > select > option { background: white; } .selection-box > select:focus { border-bottom: 2px solid #82bc00; color: #82bc00; box-shadow: 0 2px 6px 0 rgba(0,0,0,0.3); } .selection-box > label { position: absolute; cursor: pointer; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; right: 0; top: 6px; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); } .input-box { position: relative; } .input-box > input[type=text] { width: 100%; background: transparent; border: none; color: #656565; border-bottom: 2px solid #656565; outline: none; box-sizing: border-box; transition: 0.3s; } .input-box > input[type=text]:focus { color: #82bc00; border-bottom: 2px solid #82bc00; } .input-box > label { cursor: pointer; position: absolute; right: 0; top: 5px; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); }
(function (global) { System.config({ transpiler: 'ts', typescriptOptions: { tsconfig: true }, meta: { 'typescript': { "exports": "ts" }, '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'core-js': 'npm:core-js/client/shim.min.js', 'zone': 'npm:zone.js/fesm2015/zone.min.js', 'rxjs': 'npm:rxjs/dist/bundles/rxjs.umd.min.js', '@angular/core': 'npm:@angular/core/fesm2022', '@angular/common': 'npm:@angular/common/fesm2022/common.mjs', '@angular/compiler': 'npm:@angular/compiler/fesm2022/compiler.mjs', '@angular/platform-browser': 'npm:@angular/platform-browser/fesm2022/platform-browser.mjs', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/fesm2022/platform-browser-dynamic.mjs', '@angular/common/http': 'npm:@angular/common/fesm2022/http.mjs', '@angular/router': 'npm:@angular/router/fesm2022/router.mjs', '@angular/forms': 'npm:@angular/forms/fesm2022/forms.mjs', 'jszip': 'npm:jszip/dist/jszip.min.js', 'typescript': 'npm:typescript/lib/typescript.js', 'ts': './plugin.js', 'tslib':'npm:tslib/tslib.js', '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', '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-print': 'npm:@mescius/spread-sheets-print/index.js', '@mescius/spread-sheets-pdf': 'npm:@mescius/spread-sheets-pdf/index.js', '@mescius/spread-sheets-io': 'npm:@mescius/spread-sheets-io/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-ganttsheet': 'npm:@mescius/spread-sheets-ganttsheet/index.js', '@mescius/spread-sheets-angular': 'npm:@mescius/spread-sheets-angular/fesm2020/mescius-spread-sheets-angular.mjs', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'ts' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, "node_modules/@angular": { defaultExtension: 'mjs' }, "@mescius/spread-sheets-angular": { defaultExtension: 'mjs' }, '@angular/core': { defaultExtension: 'mjs', main: 'core.mjs' } } }); })(this);