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, xlsm, xltm, xltx, 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.ExcelFileType
GC.Spread.Sheets.ImportXlsxOptions
GC.Spread.Sheets.ExportXlsxOptions
GC.Spread.Sheets.ImportCsvOptions
.Spread.Sheets.ExportCsvOptions
GC.Spread.Sheets.ImportSSJsonOptions
GC.Spread.Sheets.ExportSSJsonOptions
var openOptions = [
{ 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: "incrementalCalculation", type: "boolean", default: false },
{ propName: "includeUnusedStyles", type: "boolean", default: true },
];
var importXlsxOptions = [
{ 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: "incrementalCalculation", type: "boolean", default: false },
{ propName: "includeUnusedStyles", type: "boolean", default: true },
{ propName: "convertSheetTableToDataTable", type: "boolean", default: false },
];
var importSSJsonOptions = [
{ 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 }
];
var importCsvOptions = [
{ propName: "encoding", type: "string", default: "UTF-8" },
{ propName: "rowDelimiter", type: "string", default: "\r\n" },
{ propName: "columnDelimiter", type: "string", default: "," }
];
var saveOptions = [
{ 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 },
];
var exportXlsxOptions = [
{ 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 },
{ propName: "losslessEditing", type: "boolean", default: true },
];
var exportSSJsonOptions = [
{ 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 },
];
var exportCsvOptions = [
{ 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 },
];
var FileType = {
SJS: 'sjs',
Excel: 'xlsx',
SSJson: 'ssjson',
Csv: 'csv',
}
var openOptionsDict = {};
openOptionsDict[FileType.SJS] = openOptions;
openOptionsDict[FileType.Excel] = importXlsxOptions;
openOptionsDict[FileType.SSJson] = importSSJsonOptions;
openOptionsDict[FileType.Csv] = importCsvOptions;
var saveOptionsDict = {};
saveOptionsDict[FileType.SJS] = saveOptions;
saveOptionsDict[FileType.Excel] = exportXlsxOptions;
saveOptionsDict[FileType.SSJson] = exportSSJsonOptions;
saveOptionsDict[FileType.Csv] = exportCsvOptions;
window.onload = function () {
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(document.getElementById('statusBar'));
statusBar.bind(spread);
initDefaultOptions();
var selectedFileElement = document.querySelector('#selectedFile');
selectedFileElement.addEventListener("change", function () {
var file = selectedFileElement.files[0];
updateOptions('open', getFileType(file));
});
var saveFileType = document.querySelector('#saveFileType');
saveFileType.addEventListener("change", function () {
var fileType = saveFileType.value;
updateOptions('save', fileType);
});
document.getElementById('open').onclick = function () {
var file = document.querySelector('#selectedFile').files[0];
if (!file) {
return;
}
var fileType = getFileType(file);
var options = getOptions('open');
if (fileType === FileType.SJS) {
spread.open(file, function () { }, function () { }, options);
} else {
spread.import(file, function () { }, function () { }, options);
}
};
document.getElementById('save').onclick = function () {
var fileName = 'export.' + saveFileType.value;
var fileType = saveFileType.value;
var options = getOptions('save');
if (fileType === FileType.SJS) {
spread.save(function (blob) { saveAs(blob, fileName); }, function () { }, options);
} else {
if (fileType === FileType.Csv) {
var { sheetIndex, row, rowCount, column, columnCount } = options;
options.range = {
sheetIndex: sheetIndex,
row: row,
rowCount: rowCount,
column: column,
columnCount: columnCount,
};
}
options.fileType = mapExportFileType(fileType);
if (fileType === 'xlsx') {
fileName = 'export.' + options.excelFileType.toLowerCase();
}
spread.export(function (blob) { saveAs(blob, fileName); }, function () { }, options);
}
};
};
function initOptions(options, fileType, mode) {
var container = document.createElement('div');
container.className = fileType;
container.style.display = 'none';
options.forEach(function (prop) {
var item = document.createElement('div');
item.className = 'item';
var id = getElementId(mode, fileType, prop.propName);
var label = document.createElement("label");
label.innerText = formatOptionLabel(prop.displayText || prop.propName);
label.for = id;
if (prop.type === 'select') {
var select = document.createElement('select');
prop.options.forEach(function (p) {
var option = document.createElement('option');
option.value = p.value;
option.text = p.name;
select.appendChild(option);
});
select.id = id;
select.value = prop.default;
item.appendChild(label);
item.appendChild(select);
} else {
var input = document.createElement('input');
input.id = getElementId(mode, fileType, prop.propName);
if (prop.type === 'boolean') {
input.type = 'checkbox';
input.checked = prop.default;
item.appendChild(input);
item.appendChild(label);
} else if (prop.type === 'number') {
input.type = 'number';
input.value = prop.default;
item.appendChild(label);
item.appendChild(input);
} else if (prop.type === 'string') {
input.type = 'text';
input.value = prop.default;
item.appendChild(label);
item.appendChild(input);
}
}
container.appendChild(item);
});
return container;
}
function formatOptionLabel(text) {
return text
.replace(/([a-z])([A-Z])/g, '$1 $2')
.replace(/([0-9])([A-Z][a-z])/g, '$1 $2')
.replace(/\b[a-z]/g, function (letter) {
return letter.toUpperCase();
});
}
function initDefaultOptions() {
var container = document.querySelector('.open-options');
var mode = 'open';
container.appendChild(initOptions(openOptions, FileType.SJS, mode));
container.appendChild(initOptions(importXlsxOptions, FileType.Excel, mode));
container.appendChild(initOptions(importSSJsonOptions, FileType.SSJson, mode));
container.appendChild(initOptions(importCsvOptions, FileType.Csv, mode));
container = document.querySelector('.save-options');
mode = 'save';
container.appendChild(initOptions(saveOptions, FileType.SJS, mode));
container.appendChild(initOptions(exportXlsxOptions, FileType.Excel, mode));
container.appendChild(initOptions(exportSSJsonOptions, FileType.SSJson, mode));
container.appendChild(initOptions(exportCsvOptions, FileType.Csv, mode));
updateOptions('save', FileType.SJS);
}
function updateOptions(mode, fileType) {
var container = document.querySelector('.' + mode + '-options');
var oldFileType = container.getAttribute('data-file-type');
if (oldFileType === fileType) {
return;
}
if (mode === 'save') {
var excelFileTypeContainer = document.querySelector('.excelFileTypeContainer');
excelFileTypeContainer.style.display = fileType === 'xlsx' ? 'block' : 'none';
}
if (oldFileType) {
container.querySelector('.' + oldFileType).style.display = 'none';
}
if (fileType) {
container.querySelector('.' + fileType).style.display = '';
}
container.setAttribute('data-file-type', fileType);
}
function getOptions(mode) {
var container = document.querySelector('.' + mode + '-options');
var fileType = container.getAttribute('data-file-type');
if (!fileType) {
return;
}
var options = {};
var props = mode === 'open' ? openOptionsDict[fileType] : saveOptionsDict[fileType];
container = container.querySelector('.' + fileType);
props.forEach(function (prop) {
var element = container.querySelector('#' + getElementId(mode, fileType, prop.propName));
var value;
if (prop.type === 'boolean') {
value = element.checked;
} else if (prop.type === 'number') {
value = +element.value;
} else if (prop.type === 'string') {
value = element.value;
} else if (prop.type === 'select') {
value = +element.value;
}
options[prop.propName] = value;
});
if (mode === 'save' && saveFileType.value === 'xlsx') {
var excelFileType = document.querySelector('#saveExcelFileType');
options.excelFileType = excelFileType.value;
}
return options;
}
function getElementId(mode, fileType, propName) {
return mode + '-' + fileType + '-' + propName;
}
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' || extensionName === 'xltm' || extensionName === 'xltx') {
return FileType.Excel;
} else if (extensionName === 'ssjson' || extensionName === 'json') {
return FileType.SSJson;
} else if (extensionName === 'csv') {
return FileType.Csv;
}
}
function mapExportFileType(fileType) {
if (fileType === FileType.SSJson) {
return GC.Spread.Sheets.FileType.ssjson;
} else if (fileType === FileType.Csv) {
return GC.Spread.Sheets.FileType.csv;
}
return GC.Spread.Sheets.FileType.excel;
}
<!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/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script>
<script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="sample-tutorial">
<div class="sample-container">
<div id="ss" class="sample-spreadsheets"></div>
<div id="statusBar"></div>
</div>
<aside class="options-container" aria-label="SpreadJS file format settings">
<div class="panel-header">
<h1>File Format Settings</h1>
<p class="panel-description">Open and save SpreadJS file or Excel file with format-specific import and export options.</p>
</div>
<div class="option-row">
<section class="inputContainer control-section">
<h2>Open File</h2>
<div class="file-action-row">
<label for="selectedFile">Source File</label>
<input id="selectedFile" type="file" name="files[]" accept=".sjs, .xlsx, .xlsm, .xltm, .xltx, .ssjson, .json, .csv" />
<button class="settingButton" id="open">Open</button>
</div>
<div class="open-options"></div>
</section>
<section class="inputContainer control-section">
<h2>Save File</h2>
<div class="save-action-row">
<label for="saveFileType">File Type</label>
<select id="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">Save</button>
</div>
<div class="excelFileTypeContainer">
<label for="saveExcelFileType">Excel File Type</label>
<div>
<select id="saveExcelFileType">
<option value="XLSX">Workbook (*.xlsx)</option>
<option value="XLSM">Macro-Enabled Workbook (*.xlsm)</option>
<option value="XLTM">Macro-Enabled Template (*.xltm)</option>
<option value="XLTX">Workbook Template (*.xltx)</option>
</select>
</div>
</div>
<div class="save-options"></div>
</section>
</div>
</aside>
</div>
</body>
</html>
html,
body {
height: 100%;
margin: 0;
}
body {
position: absolute;
inset: 0;
color: #1f2933;
background: #f7f8fa;
}
.sample-tutorial {
display: flex;
height: 100%;
overflow: hidden;
}
.sample-container {
display: flex;
flex: 1 1 auto;
flex-direction: column;
min-width: 0;
height: 100%;
}
.sample-spreadsheets {
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
}
#statusBar {
flex: 0 0 25px;
width: 100%;
}
.options-container {
flex: 0 0 320px;
width: 320px;
height: 100%;
padding: 18px 16px;
box-sizing: border-box;
overflow: auto;
overflow-x: hidden;
background: #ffffff;
border-left: 1px solid #e5e7eb;
}
.sample-options {
z-index: 1000;
}
.panel-header {
padding-bottom: 14px;
border-bottom: 1px solid #eef0f3;
}
.panel-header h1 {
margin: 0;
font-size: 18px;
font-weight: 650;
line-height: 1.25;
}
.panel-description {
margin: 8px 0 0;
color: #6b7280;
font-size: 13px;
line-height: 1.6;
}
.option-row {
display: grid;
}
.inputContainer {
box-sizing: border-box;
}
.control-section {
padding: 14px 0;
border-bottom: 1px solid #eef0f3;
}
.control-section:last-child {
border-bottom: 0;
}
.control-section h2 {
margin: 0 0 10px;
color: #374151;
font-size: 13px;
font-weight: 700;
line-height: 1.3;
}
.options-container label {
color: #374151;
font-size: 13px;
font-weight: 600;
line-height: 1.35;
}
.options-container select,
.options-container input[type="text"],
.options-container input[type="number"] {
width: 100%;
height: 30px;
padding: 0 8px;
box-sizing: border-box;
color: #111827;
font: inherit;
background: #ffffff;
border: 1px solid #d8dde5;
border-radius: 6px;
outline: none;
transition: border-color .15s ease, box-shadow .15s ease;
}
.options-container select:focus,
.options-container input[type="text"]:focus,
.options-container input[type="number"]:focus,
.options-container input[type="file"]:focus,
.options-container button:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, .12);
}
.options-container input[type="file"] {
display: block;
min-width: 0;
color: #374151;
font-size: 12px;
}
.options-container input[type="file"]::file-selector-button {
height: 28px;
margin-right: 8px;
padding: 0 10px;
color: #1f4f82;
font: inherit;
font-weight: 600;
cursor: pointer;
background: #ffffff;
border: 1px solid #9bb2cf;
border-radius: 4px;
}
.options-container button,
.options-container input[type="button"] {
min-height: 30px;
padding: 0 12px;
box-sizing: border-box;
color: #1f4f82;
font: inherit;
font-weight: 600;
cursor: pointer;
background: #ffffff;
border: 1px solid #9bb2cf;
border-radius: 4px;
transition: background-color .15s ease, border-color .15s ease;
}
.options-container button:hover,
.options-container input[type="button"]:hover {
background: #edf5ff;
border-color: #6f98c8;
}
.settingButton {
flex: 0 0 auto;
margin: 0;
}
.file-action-row,
.save-action-row {
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
gap: 8px;
align-items: center;
min-width: 0;
}
.file-action-row {
margin-bottom: 8px;
}
.file-action-row label,
.save-action-row label {
white-space: nowrap;
}
.file-action-row input[type="file"] {
width: 100%;
max-width: 100%;
min-width: 0;
overflow: hidden;
text-overflow: clip;
}
.save-action-row {
margin-bottom: 10px;
}
.save-action-row select {
width: 100%;
min-width: 0;
}
#open,
#save {
min-width: 56px;
}
.open-options .item,
.save-options .item {
display: flex;
gap: 8px;
align-items: center;
min-height: 24px;
margin: 4px 0;
}
.open-options .item label,
.save-options .item label {
flex: 1 1 auto;
min-width: 0;
font-weight: 500;
overflow-wrap: anywhere;
}
.open-options .item select,
.save-options .item select,
.open-options .item input[type="text"],
.save-options .item input[type="text"],
.open-options .item input[type="number"],
.save-options .item input[type="number"] {
flex: 0 0 128px;
width: 128px;
height: 28px;
}
.open-options .item input[type="checkbox"],
.save-options .item input[type="checkbox"] {
width: 16px;
height: 16px;
margin: 0;
accent-color: #2563eb;
flex: 0 0 auto;
}
.excelFileTypeContainer {
margin-bottom: 10px;
}
#saveExcelFileType {
margin: 8px 0 0;
}
@media (max-width: 760px) {
.sample-tutorial {
flex-direction: column;
}
.sample-container {
flex: 1 1 55%;
min-height: 55%;
}
.options-container {
flex: 0 0 45%;
width: 100%;
height: 45%;
border-top: 1px solid #e5e7eb;
border-left: 0;
}
}