概述
本 Demo 展示了集算表的完整导入导出功能,包括 JSON 序列化、SJS 文件格式、Excel 导出、PDF 导出以及打印功能。通过界面上的按钮,用户可以方便地将集算表数据保存为不同格式或加载已有的数据文件。
实现思路
初始化集算表并绑定数据视图
为界面按钮绑定事件处理函数
实现 JSON 格式的保存和加载功能
实现 SJS 文件格式的保存和加载功能
实现 Excel 文件导出功能
实现 PDF 导出和打印功能
代码解析
保存为 JSON 文件
使用 spread.toJSON() 方法将工作簿序列化为 JSON 对象。includeBindingSource 参数设置为 true 表示包含数据绑定源,saveAsView 参数设置为 true 表示按视图样式保存。最后使用 FileSaver 库将 JSON 数据保存为文件。
保存为 SJS 文件
使用 spread.save() 方法将工作簿保存为 SJS 格式。SJS 是 SpreadJS v16 引入的新文件格式,采用压缩结构,能够显著减小文件体积并提升大型文件的加载性能。
加载 JSON 或 SJS 文件
根据文件扩展名自动判断文件类型,JSON 文件使用 fromJSON 方法加载,SJS 文件使用 open 方法加载。
导出为 Excel 文件
使用 spread.export() 方法导出为 Excel 文件。对于集算表导出 Excel,建议将 includeBindingSource 参数设置为 true 以包含绑定数据。
导出为 PDF 和打印
使用 savePDF 方法导出 PDF 文件,使用 print 方法调用浏览器打印功能。
运行效果
点击"JSON"按钮,将集算表保存为 .ssjson 文件
点击"SJS"按钮,将集算表保存为 .sjs 文件
点击"JSON 或 SJS"按钮,可以加载本地的 JSON 或 SJS 文件
点击"Excel"按钮,将集算表导出为 .xlsx 文件
点击"PDF"按钮,将集算表导出为 PDF 文件
点击"打印"按钮,调用浏览器打印功能
API 参考
toJSON 方法
serializationOption.includeBindingSource:是否包含绑定数据源
serializationOption.saveAsView:是否按视图样式保存
save 方法
successCallback:保存成功的回调函数,接收 Blob 参数
errorCallback:保存失败的回调函数
saveOptions:保存选项,如 includeBindingSource、saveAsView 等
export 方法
options.fileType:导出文件类型,如 GC.Spread.Sheets.FileType.excel
options.includeBindingSource:是否包含绑定数据源
savePDF 方法
successCallback:导出成功的回调函数
errorCallback:导出失败的回调函数
sheetIndex:指定导出的工作表索引
/*REPLACE_MARKER*/
/*DO NOT DELETE THESE COMMENTS*/
window.onload = function() {
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 0 });
initSpread(spread);
initEvent(spread);
};
function initSpread(spread) {
spread.suspendPaint();
spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader;
spread.options.highlightInvalidData = true;
//init a data manager
var baseApiUrl = getBaseApiUrl();
var dataManager = spread.dataManager();
//add product table
var productTable = dataManager.addTable("productTable", {
remote: {
read: {
url: baseApiUrl + "/Product"
}
}
});
//init a table sheet
var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet);
sheet.options.allowAddNew = false; //hide new row
sheet.setDefaultRowHeight(40, GC.Spread.Sheets.SheetArea.colHeader);
//bind a view to the table sheet
var numericStyle = {};
numericStyle.formatter = "$ 0.00";
var formulaRule = {
ruleType: "formulaRule",
formula: "@>=50",
style: {
font:"bold 12pt Calibri",
backColor: "#F7D3BA",
foreColor :"#F09478"
}
};
var positiveNumberValidator = {
type: "formula",
formula: '@<50',
inputTitle: 'Data validation:',
inputMessage: 'Enter a number smaller than 50.',
highlightStyle: {
type: 'icon',
color: "#F09478",
position: 'outsideRight',
}
};
var myView = productTable.addView("myView", [
{ value: "Id", caption: "ID", width: 46},
{ value: "ProductName", caption: "Name", width: 200 },
{ value: "UnitPrice", caption: "Unit Price", width: 140, conditionalFormats: [formulaRule], validator: positiveNumberValidator, style: numericStyle },
{ value: "=SUM([@UnitsInStock] , [@UnitsOnOrder])", caption: "Total Units", width: 140},
{ value: "Discontinued", width: 120, style:{formatter:"[green]✔;;[red]✘"}}
]);
myView.fetch().then(function() {
sheet.setDataView(myView);
});
spread.resumePaint();
}
function initEvent(spread) {
document.getElementById('toJSON').onclick = function() {
var json = spread.toJSON({ includeBindingSource: true, saveAsView: true });
saveAs(new Blob([JSON.stringify(json)], { type: "text/plain;charset=utf-8" }), 'download.ssjson');
};
document.getElementById('toSJS').onclick = function() {
spread.save(function (blob) {
saveAs(blob, 'download.sjs');
}, function (e) {
console.log(e);
});
}
document.getElementById('fromJSONOrSJS').onclick = function() {
var file = document.getElementById("fileDemo").files[0];
if (file) {
var suffix = file.name.substr(file.name.lastIndexOf(".") + 1).toLowerCase();
if (suffix === "ssjson" || suffix === "json") {
var reader = new FileReader();
reader.onload = function() {
var json = JSON.parse(this.result);
spread.fromJSON(json);
};
reader.readAsText(file);
} else if (suffix === 'sjs') {
spread.open(file, function () {
}, function (e) {
console.log(e); // error callback
});
}
}
};
document.getElementById('saveExcel').onclick = function() {
spread.export(function (blob) {
saveAs(blob, "export.xlsx");
}, function(e) {
console.log(e);
}, {
fileType: GC.Spread.Sheets.FileType.excel
});
};
document.getElementById('exportPDF').onclick = function() {
spread.savePDF(function(blob) {
saveAs(blob, "export.pdf");
}, function(error) {
console.log(error);
}, null, spread.getSheetCount() + spread.getActiveSheetTabIndex());
};
document.getElementById('print').onclick = function() {
spread.print();
};
}
function getBaseApiUrl() {
return window.location.href.match(/http.+spreadjs\/SpreadJSTutorial\//)[0] + 'server/api';
}
<!doctype html>
<html style="height:100%;font-size:14px;">
<head>
<meta name="spreadjs culture" content="zh-cn" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css"
href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<!-- Promise Polyfill for IE, https://www.npmjs.com/package/promise-polyfill -->
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>
<script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/dist/gc.spread.sheets.all.min.js"
type="text/javascript"></script>
<script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script>
<script
src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-print/dist/gc.spread.sheets.print.min.js"
type="text/javascript"></script>
<script
src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js"
type="text/javascript"></script>
<script
src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js"
type="text/javascript"></script>
<script
src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.min.js"
type="text/javascript"></script>
<script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-io/dist/gc.spread.sheets.io.min.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 id="ss" class="sample-spreadsheets"></div>
<div class="options-container">
<fieldset>
<legend>保存</legend>
<div class="field-line">
<input type="button" id="toJSON" value="JSON" class="button">
</div>
<div class="field-line">
<input type="button" id="toSJS" value="SJS" class="button">
</div>
<div class="field-line">
<input type="button" id="saveExcel" value="Excel" class="button">
</div>
</fieldset>
<fieldset>
<legend>加载</legend>
<div class="field-line">
<input type="file" id="fileDemo" class="input">
</div>
<div class="field-line">
<input type="button" id="fromJSONOrSJS" value="JSON 或 SJS" class="button">
</div>
</fieldset>
<fieldset>
<legend>渲染</legend>
<div class="field-line">
<input type="button" id="exportPDF" value="PDF" class="button">
</div>
<div class="field-line">
<input type="button" id="print" value="打印" class="button">
</div>
</fieldset>
</div>
</div>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: hidden;
float: left;
}
.options-container {
float: right;
width: 280px;
padding: 12px;
height: 100%;
box-sizing: border-box;
background: #fbfbfb;
overflow: auto;
}
.sample-options {
z-index: 1000;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
fieldset {
padding: 6px;
margin: 0;
margin-top: 10px;
}
fieldset span,
fieldset input,
fieldset select {
display: inline-block;
text-align: left;
}
fieldset input[type=text] {
width: calc(100% - 58px);
}
fieldset input[type=button] {
width: 100%;
text-align: center;
}
fieldset input[type=file] {
width: 100%;
text-align: left;
}
fieldset select {
width: calc(100% - 50px);
}
.field-line {
margin-top: 4px;
}
.field-inline {
display: inline-block;
vertical-align: middle;
}
fieldset label.field-inline {
width: 100px;
}
fieldset input.field-inline {
width: calc(100% - 100px - 12px);
}