Import & Export

SpreadJS supports the opening and saving to several popular file formats including Excel .xlsx/.xlsm, .csv, .ssjson (older SpreadJS format) and the new faster .sjs SpreadJS file formats. The new .sjs format significantly improves the load time and memory usage when working with very large Excel files while greatly reducing the file size when resaved as compared to previous SpreadJS versions.

Learn more about opening password protected Excel files.

In order to use the SpreadJS File Format feature, you need to add the related js file link into the document's head section below the Spread link. For example: SpreadJS supports opening and saving sjs file formats. It also supports importing and exporting xlsx, ssjson, and csv file formats. For example: class GC.Spread.Sheets.Workbook GC.Spread.Sheets.SaveOptions GC.Spread.Sheets.OpenOptions GC.Spread.Sheets.ImportOptions GC.Spread.Sheets.ExportOptions GC.Spread.Sheets.ImportXlsxOptions GC.Spread.Sheets.ExportXlsxOptions GC.Spread.Sheets.ImportCsvOptions .Spread.Sheets.ExportCsvOptions GC.Spread.Sheets.ImportSSJsonOptions GC.Spread.Sheets.ExportSSJsonOptions
<template> <div class="sample-tutorial"> <div class="sample-container"> <gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread"> <gc-worksheet> </gc-worksheet> </gc-spread-sheets> <div id="statusBar"></div> </div> <div class="options-container"> <div class="option-row"> <div class="inputContainer"> <input id="selectedFile" type="file" accept=".sjs, .xlsx, .xlsm, .ssjson, .json, .csv" v-on:change="selectedFileChange($event)" /> <button class="settingButton" id="open" v-on:click="open">Open</button> <div class="open-options"> <div class="item" v-show="needShow('open', 'openMode')"> <label for="open-openMode">OpenMode</label> <select id="open-openMode" v-model.number="openOptions.openMode"> <option value="0">normal</option> <option value="1">lazy</option> <option value="2">incremental</option> </select> </div> <div class="item" v-show="needShow('open', 'includeStyles')" > <input type="checkbox" id="open-includeStyles" v-model="openOptions.includeStyles"/> <label for="open-includeStyles">includeStyles</label> </div> <div class="item" v-show="needShow('open', 'includeFormulas')" > <input type="checkbox" id="open-includeFormulas" v-model="openOptions.includeFormulas"/> <label for="open-includeFormulas">includeFormulas</label> </div> <div class="item" v-show="needShow('open', 'frozenColumnsAsRowHeaders')" > <input type="checkbox" id="open-frozenColumnsAsRowHeaders" v-model="openOptions.frozenColumnsAsRowHeaders"/> <label for="open-frozenColumnsAsRowHeaders">frozenColumnsAsRowHeaders</label> </div> <div class="item" v-show="needShow('open', 'frozenRowsAsColumnHeaders')" > <input type="checkbox" id="open-frozenRowsAsColumnHeaders" v-model="openOptions.frozenRowsAsColumnHeaders"/> <label for="open-frozenRowsAsColumnHeaders">frozenRowsAsColumnHeaders</label> </div> <div class="item" v-show="needShow('open', 'fullRecalc')" > <input type="checkbox" id="open-fullRecalc" v-model="openOptions.fullRecalc"/> <label for="open-fullRecalc">fullRecalc</label> </div> <div class="item" v-show="needShow('open', 'dynamicReferences')" > <input type="checkbox" id="open-dynamicReferences" v-model="openOptions.dynamicReferences"/> <label for="open-dynamicReferences">dynamicReferences</label> </div> <div class="item" v-show="needShow('open', 'calcOnDemand')" > <input type="checkbox" id="open-calcOnDemand" v-model="openOptions.calcOnDemand"/> <label for="open-calcOnDemand">calcOnDemand</label> </div> <div class="item" v-show="needShow('open', 'includeUnusedStyles')" > <input type="checkbox" id="open-includeUnusedStyles" v-model="openOptions.includeUnusedStyles"/> <label for="open-includeUnusedStyles">includeUnusedStyles</label> </div> <div class="item" v-show="needShow('open', 'incrementalLoading')" > <input type="checkbox" id="open-incrementalLoading" v-model="openOptions.incrementalLoading"/> <label for="open-incrementalLoading">incrementalLoading</label> </div> <div class="item" v-show="needShow('open', 'encoding')" > <label for="open-encoding">encoding</label> <input type="text" id="open-encoding" v-model="openOptions.encoding"/> </div> <div class="item" v-show="needShow('open', 'rowDelimiter')" > <label for="open-rowDelimiter">rowDelimiter</label> <input type="text" id="open-rowDelimiter" v-model="openOptions.rowDelimiter"/> </div> <div class="item" v-show="needShow('open', 'columnDelimiter')" > <label for="open-columnDelimiter">columnDelimiter</label> <input type="text" id="open-columnDelimiter" v-model="openOptions.columnDelimiter"/> </div> </div> </div> <div class="inputContainer"> <label for="saveFileType">FileType:</label> <select id="saveFileType" v-model="saveFileType"> <option value="sjs">SJS</option> <option value="xlsx">Excel</option> <option value="ssjson">SSJson</option> <option value="csv">Csv</option> </select> <button class="settingButton" id="save" v-on:click="save">Save</button> <div class="save-options"> <div class="item" v-show="needShow('save', 'includeBindingSource')" > <input type="checkbox" id="save-includeBindingSource" v-model="saveOptions.includeBindingSource"/> <label for="save-includeBindingSource">includeBindingSource</label> </div> <div class="item" v-show="needShow('save', 'includeStyles')" > <input type="checkbox" id="save-includeStyles" v-model="saveOptions.includeStyles"/> <label for="save-includeStyles">includeStyles</label> </div> <div class="item" v-show="needShow('save', 'includeFormulas')" > <input type="checkbox" id="save-includeFormulas" v-model="saveOptions.includeFormulas"/> <label for="save-includeFormulas">includeFormulas</label> </div> <div class="item" v-show="needShow('save', 'saveAsView')" > <input type="checkbox" id="save-saveAsView" v-model="saveOptions.saveAsView"/> <label for="save-saveAsView">saveAsView</label> </div> <div class="item" v-show="needShow('save', 'rowHeadersAsFrozenColumns')" > <input type="checkbox" id="save-rowHeadersAsFrozenColumns" v-model="saveOptions.rowHeadersAsFrozenColumns"/> <label for="save-rowHeadersAsFrozenColumns">rowHeadersAsFrozenColumns</label> </div> <div class="item" v-show="needShow('save', 'columnHeadersAsFrozenRows')" > <input type="checkbox" id="save-columnHeadersAsFrozenRows" v-model="saveOptions.columnHeadersAsFrozenRows"/> <label for="save-columnHeadersAsFrozenRows">columnHeadersAsFrozenRows</label> </div> <div class="item" v-show="needShow('save', 'includeAutoMergedCells')" > <input type="checkbox" id="save-includeAutoMergedCells" v-model="saveOptions.includeAutoMergedCells"/> <label for="save-includeAutoMergedCells">includeAutoMergedCells</label> </div> <div class="item" v-show="needShow('save', 'includeCalcModelCache')" > <input type="checkbox" id="save-includeCalcModelCache" v-model="saveOptions.includeCalcModelCache"/> <label for="save-includeCalcModelCache">includeCalcModelCache</label> </div> <div class="item" v-show="needShow('save', 'saveR1C1Formula')" > <input type="checkbox" id="save-saveR1C1Formula" v-model="saveOptions.saveR1C1Formula"/> <label for="save-saveR1C1Formula">saveR1C1Formula</label> </div> <div class="item" v-show="needShow('save', 'includeUnusedNames')" > <input type="checkbox" id="save-includeUnusedNames" v-model="saveOptions.includeUnusedNames"/> <label for="save-includeUnusedNames">includeUnusedNames</label> </div> <div class="item" v-show="needShow('save', 'includeEmptyRegionCells')" > <input type="checkbox" id="save-includeEmptyRegionCells" v-model="saveOptions.includeEmptyRegionCells"/> <label for="save-includeEmptyRegionCells">includeEmptyRegionCells</label> </div> <div class="item" v-show="needShow('save', 'encoding')" > <label for="save-encoding">encoding</label> <input type="text" id="save-encoding" v-model="saveOptions.encoding"/> </div> <div class="item" v-show="needShow('save', 'rowDelimiter')" > <label for="save-rowDelimiter">rowDelimiter</label> <input type="text" id="save-rowDelimiter" v-model="saveOptions.rowDelimiter"/> </div> <div class="item" v-show="needShow('save', 'columnDelimiter')" > <label for="save-columnDelimiter">columnDelimiter</label> <input type="text" id="save-columnDelimiter" v-model="saveOptions.columnDelimiter"/> </div> <div class="item" v-show="needShow('save', 'sheetIndex')" > <label for="save-sheetIndex">sheetIndex</label> <input type="number" id="save-sheetIndex" v-model.number="saveOptions.sheetIndex"/> </div> <div class="item" v-show="needShow('save', 'row')" > <label for="save-row">row</label> <input type="number" id="save-row" v-model.number="saveOptions.row"/> </div> <div class="item" v-show="needShow('save', 'column')" > <label for="save-column">column</label> <input type="number" id="save-column" v-model.number="saveOptions.column"/> </div> <div class="item" v-show="needShow('save', 'rowCount')" > <label for="save-rowCount">rowCount</label> <input type="number" id="save-rowCount" v-model.number="saveOptions.rowCount"/> </div> <div class="item" v-show="needShow('save', 'columnCount')" > <label for="save-columnCount">columnCount</label> <input type="number" id="save-columnCount" v-model.number="saveOptions.columnCount"/> </div> </div> </div> </div> </div> </div> </template> <script> import Vue from "vue"; import "@mescius/spread-sheets-vue"; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-print'; import '@mescius/spread-sheets-io'; import '@mescius/spread-sheets-shapes'; import '@mescius/spread-sheets-charts'; import '@mescius/spread-sheets-slicers'; import '@mescius/spread-sheets-pivot-addon'; import '@mescius/spread-sheets-reportsheet-addon'; import "@mescius/spread-sheets-tablesheet"; import "@mescius/spread-sheets-ganttsheet"; import "./styles.css"; window.GC = GC; let App = Vue.extend({ name: "app", data: function () { return { spread: null, selectedFile: null, openFileType: "", saveFileType: "sjs", openOptions: { openMode: 0, includeStyles: true, includeFormulas: true, frozenColumnsAsRowHeaders: false, frozenRowsAsColumnHeaders: false, fullRecalc: false, dynamicReferences: true, calcOnDemand: false, includeUnusedStyles: true, incrementalLoading: false, encoding: "UTF-8", rowDelimiter: "\r\n", columnDelimiter: "," }, saveOptions: { includeBindingSource: false, includeStyles: true, includeFormulas: true, saveAsView: false, rowHeadersAsFrozenColumns: false, columnHeadersAsFrozenRows: false, includeAutoMergedCells: false, includeCalcModelCache: false, saveR1C1Formula: false, includeUnusedNames: true, includeEmptyRegionCells: true, encoding: "UTF-8", rowDelimiter: "\r\n", columnDelimiter: ",", sheetIndex: 0, row: 0, column: 0, rowCount: 200, columnCount: 20, }, openOptionsConfig: { sjs: [ { propName: "openMode", type: "select", displayText: "OpenMode", options: [{name: 'normal', value: 0}, {name: 'lazy', value: 1}, {name: 'incremental', value: 2}], default: 0 }, { propName: "includeStyles", type: "boolean", default: true }, { propName: "includeFormulas", type: "boolean", default: true }, { propName: "fullRecalc", type: "boolean", default: false }, { propName: "dynamicReferences", type: "boolean", default: true }, { propName: "calcOnDemand", type: "boolean", default: false }, { propName: "includeUnusedStyles", type: "boolean", default: true }, ], xlsx: [ { propName: "openMode", type: "select", displayText: "OpenMode", options: [{name: 'normal', value: 0}, {name: 'lazy', value: 1}, {name: 'incremental', value: 2}], default: 0 }, { propName: "includeStyles", type: "boolean", default: true }, { propName: "includeFormulas", type: "boolean", default: true }, { propName: "frozenColumnsAsRowHeaders", type: "boolean", default: false }, { propName: "frozenRowsAsColumnHeaders", type: "boolean", default: false }, { propName: "fullRecalc", type: "boolean", default: false }, { propName: "dynamicReferences", type: "boolean", default: true }, { propName: "calcOnDemand", type: "boolean", default: false }, { propName: "includeUnusedStyles", type: "boolean", default: true }, ], ssjson: [ { propName: "includeStyles", type: "boolean", default: true }, { propName: "includeFormulas", type: "boolean", default: true }, { propName: "frozenColumnsAsRowHeaders", type: "boolean", default: false }, { propName: "frozenRowsAsColumnHeaders", type: "boolean", default: false }, { propName: "fullRecalc", type: "boolean", default: false }, { propName: "incrementalLoading", type: "boolean", default: false } ], csv: [ { propName: "encoding", type: "string", default: "UTF-8" }, { propName: "rowDelimiter", type: "string", default: "\r\n" }, { propName: "columnDelimiter", type: "string", default: "," } ] }, saveOptionsConfig: { sjs: [ { propName: "includeBindingSource", type: "boolean", default: false }, { propName: "includeStyles", type: "boolean", default: true }, { propName: "includeFormulas", type: "boolean", default: true }, { propName: "saveAsView", type: "boolean", default: false }, { propName: "includeAutoMergedCells", type: "boolean", default: false }, { propName: "includeCalcModelCache", type: "boolean", default: false }, { propName: "saveR1C1Formula", type: "boolean", default: false }, { propName: "includeUnusedNames", type: "boolean", default: true }, { propName: "includeEmptyRegionCells", type: "boolean", default: true }, ], xlsx: [ { propName: "includeBindingSource", type: "boolean", default: false }, { propName: "includeStyles", type: "boolean", default: true }, { propName: "includeFormulas", type: "boolean", default: true }, { propName: "saveAsView", type: "boolean", default: false }, { propName: "rowHeadersAsFrozenColumns", type: "boolean", default: false }, { propName: "columnHeadersAsFrozenRows", type: "boolean", default: false }, { propName: "includeAutoMergedCells", type: "boolean", default: false }, { propName: "includeUnusedNames", type: "boolean", default: true }, { propName: "includeEmptyRegionCells", type: "boolean", default: true }, ], ssjson: [ { propName: "includeBindingSource", type: "boolean", default: false }, { propName: "includeStyles", type: "boolean", default: true }, { propName: "includeFormulas", type: "boolean", default: true }, { propName: "saveAsView", type: "boolean", default: false }, { propName: "rowHeadersAsFrozenColumns", type: "boolean", default: false }, { propName: "columnHeadersAsFrozenRows", type: "boolean", default: false }, { propName: "includeAutoMergedCells", type: "boolean", default: false }, ], csv: [ { propName: "encoding", type: "string", default: "UTF-8" }, { propName: "rowDelimiter", type: "string", default: "\r\n" }, { propName: "columnDelimiter", type: "string", default: "," }, { propName: "sheetIndex", type: "number", default: 0 }, { propName: "row", type: "number", default: 0 }, { propName: "column", type: "number", default: 0 }, { propName: "rowCount", type: "number", default: 200 }, { propName: "columnCount", type: "number", default: 20 }, ] } }; }, methods: { initSpread: function (spread) { this.spread = spread; var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(document.getElementById('statusBar')); statusBar.bind(spread); }, selectedFileChange(e) { this.selectedFile = e.target.files[0]; this.openFileType = this.getFileType(this.selectedFile); }, open() { var file = this.selectedFile; if (!file) { return; } var fileType = this.getFileType(file); var options = this.getOptions('open'); if (fileType === 'sjs') { this.spread.open(file, function() {}, function() {}, options); } else { this.spread.import(file, function() {}, function() {}, options); } }, save() { var fileType = this.saveFileType; var fileName = 'export.' + fileType; var options = this.getOptions('save'); if (fileType === 'sjs') { this.spread.save(function(blob) { saveAs(blob, fileName); }, function() {}, options); } else { options.fileType = this.mapExportFileType(fileType); this.spread.export(function(blob) { saveAs(blob, fileName); }, function() {}, options); } }, getOptions (mode) { let optionsConfig, optionsValue; if (mode === 'open') { optionsConfig = this.openOptionsConfig[this.openFileType]; optionsValue = this.openOptions; } else { optionsConfig = this.saveOptionsConfig[this.saveFileType]; optionsValue = this.saveOptions; } let options = {}; optionsConfig.forEach((prop) => { let v = optionsValue[prop.propName]; if (prop.type === 'number') { v = +v; } options[prop.propName] = v; }); return options; }, getFileType(file) { if (!file) { return; } var fileName = file.name; var extensionName = fileName.substring(fileName.lastIndexOf(".") + 1); if (extensionName === 'sjs') { return 'sjs'; } else if (extensionName === 'xlsx' || extensionName === 'xlsm') { return 'xlsx'; } else if (extensionName === 'ssjson' || extensionName === 'json') { return 'ssjson'; } else if (extensionName === 'csv') { return 'csv'; } }, mapExportFileType (fileType) { if (fileType === 'ssjson') { return GC.Spread.Sheets.FileType.ssjson; } else if (fileType === 'csv') { return GC.Spread.Sheets.FileType.csv; } return GC.Spread.Sheets.FileType.excel; }, needShow(mode, propName) { let options = mode === 'open' ? this.openOptionsConfig[this.openFileType] : this.saveOptionsConfig[this.saveFileType]; return options && options.find((p) => p.propName === propName); } } }); new Vue({ render: h => h(App) }).$mount("#app"); </script>
<!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/vue/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script> <!-- SystemJS --> <script src="$DEMOROOT$/en/vue/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); System.import('$DEMOROOT$/en/lib/vue/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-container { width: calc(100% - 280px); height: 100%; float: left; } .sample-spreadsheets { width: 100%; height: calc(100% - 25px); overflow: hidden; } #statusBar { bottom: 0; height: 25px; width: 100%; position: relative; } .options-container { float: right; width: 280px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .sample-options { z-index: 1000; } .inputContainer { width: 100%; height: auto; border: 1px solid #eee; padding: 6px 12px; margin-bottom: 10px; box-sizing: border-box; } .settingButton { color: #fff; background: #82bc00; outline: 0; line-height: 1.5715; position: relative; display: inline-block; font-weight: 400; white-space: nowrap; text-align: center; height: 32px; padding: 4px 15px; font-size: 14px; border-radius: 2px; user-select: none; cursor: pointer; border: 1px solid #82bc00; box-sizing: border-box; margin-bottom: 10px; margin-top: 10px; } .settingButton:hover { color: #fff; border-color: #88b031; background: #88b031; } .options-title { font-weight: bold; margin: 4px 2px; } #selectedFile { width: 180px; } #saveFileType { width: 120px; height: 31px; } .open-options .item { margin: 5px 0px; display: flex; } .save-options .item { margin: 5px 0px; display: flex; } label { margin-left: 3px; } select, input[type="text"], input[type="number"] { display: inline-block; margin-left: auto; width: 120px; font-weight: 400; outline: 0; line-height: 1.5715; border-radius: 2px; border: 1px solid #F4F8EB; box-sizing: border-box; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' }, '*.vue': { loader: 'vue-loader' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-print': 'npm:@mescius/spread-sheets-print/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js', '@mescius/spread-sheets-io': 'npm:@mescius/spread-sheets-io/index.js', '@mescius/spread-sheets-charts': 'npm:@mescius/spread-sheets-charts/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-slicers': 'npm:@mescius/spread-sheets-slicers/index.js', '@mescius/spread-sheets-pivot-addon': 'npm:@mescius/spread-sheets-pivot-addon/index.js', '@mescius/spread-sheets-reportsheet-addon': 'npm:@mescius/spread-sheets-reportsheet-addon/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-ganttsheet': 'npm:@mescius/spread-sheets-ganttsheet/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'css': 'npm:systemjs-plugin-css/css.js', 'vue': 'npm:vue/dist/vue.min.js', 'vue-loader': 'npm:systemjs-vue-browser/index.js', 'tiny-emitter': 'npm:tiny-emitter/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' } } }); })(this);