GanttSheet 文件导入导出

GanttSheet 支持完整的文件导入导出功能,可以导入和导出多种文件格式,包括 SJS、SSJSON、Excel 等。同时还支持打印和导出为 PDF,满足项目管理中对甘特图数据的存储、共享和输出需求。

概述 本 Demo 展示了 GanttSheet 的文件导入导出功能,包括打开不同格式的文件、导出为多种格式、打印和导出 PDF。Demo 中演示了如何使用 SpreadJS 的 IO API 处理甘特图工作表的文件操作。 实现思路 初始化 GanttSheet 并绑定数据源 实现文件打开功能,根据文件类型调用不同的 API(SJS 文件使用 spread.open(),其他格式使用 spread.import()) 实现文件导出功能,支持导出为 JSON、SJS 和 Excel 格式 实现打印功能,使用 spread.print() 方法 实现 PDF 导出功能,使用 spread.savePDF() 方法 代码解析 初始化 GanttSheet 这段代码创建了一个 GanttSheet 并将其添加到工作簿中,然后创建数据视图并绑定到 GanttSheet。 打开文件 这段代码根据文件扩展名判断文件类型,对于 SJS 文件使用 spread.open() 方法,其他格式(Excel、SSJSON)使用 spread.import() 方法。 导出文件 这段代码展示了如何导出不同格式的文件。关键配置 includeBindingSource: true 确保导出时包含绑定数据源,这对 GanttSheet 导出 Excel 尤为重要。注意:甘特图列在 Excel 中将以图片形式导出。 打印和导出 PDF spread.print() 方法用于打印工作簿,spread.savePDF() 方法将工作簿导出为 PDF 文件。 运行效果 点击「打开文件」按钮可以选择本地文件导入,支持 .sjs、.xlsx、.ssjson、.json 等格式 点击「导出为 JSON」按钮将工作簿导出为 SSJSON 格式 点击「导出为 SJS」按钮将工作簿保存为 SJS 格式(压缩文件,体积更小) 点击「导出为 Excel」按钮将工作簿导出为 Excel 文件,甘特图列以图片形式保存 点击「打印」按钮调用浏览器打印功能 点击「PDF」按钮将工作簿导出为 PDF 文件 API 参考 spread.open(file, successCallback?, errorCallback?, openOptions?) file:File 类型,SJS 文件流 successCallback:成功回调函数 errorCallback:错误回调函数 openOptions:打开选项,包含 openMode、includeStyles 等配置 spread.import(file, successCallback?, errorCallback?, importOptions?) file:File 类型,Excel、SSJSON 或 CSV 文件 importOptions:导入选项,可通过 fileType 指定文件类型 spread.save(successCallback?, errorCallback?, saveOptions?) saveOptions:保存选项,包含 includeBindingSource、includeStyles 等配置 spread.export(successCallback?, errorCallback?, exportOptions?) exportOptions:导出选项,必须设置 fileType 和 includeBindingSource 属性 spread.print(sheetIndex?) sheetIndex:可选参数,指定要打印的工作表索引,不指定则打印所有可见工作表 spread.savePDF(successCallback, errorCallback, options?, sheetIndex?) successCallback:成功回调,接收 Blob 参数 errorCallback:错误回调 options:PDF 导出选项,可设置 title、author、subject 等元数据 sheetIndex:可选,指定要导出的工作表索引
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ var spread; var myTable; var ganttSheet; var FileType = { SJS: 'sjs', Excel: 'xlsx', SSJson: 'ssjson' }; var openOptions = { openMode: GC.Spread.Sheets.OpenMode.normal, fullRecalc: true }; window.onload = function() { spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 0 }); initSpread(spread); initSplitView(spread); }; function initSpread(spread) { spread.suspendPaint(); initDataSource(spread); initGanttSheet(spread); spread.resumePaint(); } function initDataSource(spread) { var tableName = "Gantt_Id"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); myTable = dataManager.addTable("myTable", { batch: true, remote: { read: { url: apiUrl } }, schema: { hierarchy: { type: "Parent", column: "parentId" }, columns: { id: { isPrimaryKey: true }, taskNumber: { dataType: "rowOrder" } } } }); } function initGanttSheet(spread) { ganttSheet = spread.addSheetTab(0, "GanttSheet", GC.Spread.Sheets.SheetType.ganttSheet); var view = 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); }); initSidePanel(spread, ganttSheet); } function initSidePanel(spread, ganttSheet) { var fileInput = document.getElementById("file-input"); var openFileItem = document.getElementById("open-file"); var fileNameItem = document.getElementById("file-name"); var exportJSONItem = document.getElementById("export-to-json"); var exportSJSItem = document.getElementById("export-to-sjs"); var exportExcelItem = document.getElementById("export-to-excel"); var printItem = document.getElementById("print"); var pdfItem = document.getElementById("pdf"); openFileItem.addEventListener('click', function() { fileInput.click(); }); fileInput.addEventListener('change', function(e) { openFile(e, fileNameItem, fileInput); }); exportJSONItem.addEventListener('click', function () { exportFile(FileType.SSJson); }); exportSJSItem.addEventListener('click', function () { exportFile(FileType.SJS); }); exportExcelItem.addEventListener('click', function () { exportFile(FileType.Excel); }); printItem.addEventListener('click', function() { printSpread(); }); pdfItem.addEventListener('click', function() { savePDF(); }); } 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 openFile(e) { 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) { // here is excel IO API spread.open(file, function() { fileNameItem.value = fileName; fileInput.value = ''; }, function() {}, openOptions); // process error } else { spread.import(file, function() { fileNameItem.value = fileName; fileInput.value = ''; }, function() {}, openOptions); } } function getExportOptions(fileType) { return { // process error fileType: GC.Spread.Sheets.FileType[fileType], includeBindingSource: true, saveAsView: true }; } function exportFile(fileType) { var fileName = 'export.' + fileType; var options = getExportOptions(fileType); if (fileType === FileType.SJS) { spread.save(function(blob) { saveAs(blob, fileName); }, function() {}, options); // here is excel IO API // process error } else { spread.export(function(blob) { saveAs(blob, fileName); }, function() {}, options); } } function printSpread() { spread.print(); } function savePDF() { spread.savePDF( function (blob) { saveAs(blob, 'download.pdf'); }, function () {} ); } function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/SpreadJSTutorial\//)[0] + 'server/api'; } 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(); } }); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="spreadjs culture" content="zh-cn" /> <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"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/spread/source/splitView/splitView.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$/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-io/dist/gc.spread.sheets.io.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-ganttsheet/dist/gc.spread.sheets.ganttsheet.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$/spread/source/splitView/splitView.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/FileSaver.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 id="split-view" class="sample-tutorial"> <div id="ss" class="sample-spreadsheets split-content"></div> <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" /> <div class="option-row input-box"> <label for="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="打开文件" /> <div class="option-info">文件类型:*.ssjson, *.sjs</div> </div> </div> <div class="option-block"> <div class="option-row"> <input type="button" id="export-to-json" class="option-button" value="导出为 JSON" /> </div> <div class="option-row"> <input type="button" id="export-to-sjs" class="option-button" value="导出为 SJS" /> </div> <div class="option-row"> <input type="button" id="export-to-excel" class="option-button" value="导出为 Excel" /> </div> </div> <div class="option-block"> <div class="option-row"> <input type="button" id="print" class="option-button" value="打印" /> </div> <div class="option-row"> <input type="button" id="pdf" class="option-button" value="PDF" /> </div> </div> </div> </div> </html>
.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); }