将 SparklineEx 导出为图片

概述 本示例展示了如何在 SpreadJS 中准备 SparklineEx 和条码内容,并通过导出配置将这些扩展可视化内容以图片形式写入 Excel 文件。 示例包含两个工作表:第一张工作表生成柱形迷你图,第二张工作表生成多种 Code128 条码效果。页面顶部的工具栏会绑定当前工作簿,用户可以基于这些内容执行导出操作。 实现思路 页面加载后创建一个包含两张工作表的 Workbook,并把工作簿实例挂接到自定义工具栏组件上。 第一张工作表使用销售数据和 COLUMNSPARKLINE 公式批量生成 SparklineEx 示例。 第二张工作表使用 BC_CODE128 公式生成默认、隐藏标签和自定义标签字体三种条码效果。 通过单独的样式函数统一设置行高、列宽、合并单元格和边框,使导出后的视觉效果更稳定。 导出时由工具栏侧调用保存逻辑,在 Excel 导出配置里把 saveAsView 设为 true,从而将 SparklineEx 或自定义迷你图按图片视图导出。 代码解析 示例入口会先创建工作簿,再把它交给页面中的工具栏组件,之后分别初始化两张工作表: 第一张工作表通过二维数组写入销售数据,再逐行为最后一列设置 COLUMNSPARKLINE 公式。这样每位销售人员都会生成一条与月份销售数据对应的柱形迷你图: 第二张工作表演示条码类扩展可视化内容。这里使用同一个 BC_CODE128 公式,分别生成默认显示、隐藏标签和自定义标签字体三种效果: 为了保证条码展示区域在页面中和导出后都保持清晰,示例对行高、列宽、合并单元格和边框做了集中处理: 这个 demo 的导出重点不在 app.js 中直接调用保存,而是在工具栏侧配合工作簿执行导出。实现思路与下面的配置一致:当导出 Excel 时,把 saveAsView 设为 true,即可将 SparklineEx 作为图片视图写入结果文件。 运行效果 页面打开后会显示两个工作表:一个用于展示销售数据对应的柱形迷你图,另一个用于展示不同标签样式的 Code128 条码。 第一张工作表中,每条销售记录右侧都会自动生成一张柱形迷你图。 第二张工作表中,同一条号码会以多种条码展示方式并排呈现,便于对比标签显示差异。 页面顶部的工具栏会绑定当前工作簿,用于触发保存或导出操作。 在导出 Excel 时,如果启用了 saveAsView: true,这些扩展可视化内容会以图片形式输出到结果文件中。 API 参考 sheet.setFormula(row, col, formula) 用于写入 COLUMNSPARKLINE 和 BC_CODE128 公式。 sheet.setArray(row, col, values) 用于批量写入销售数据和条码示例数据。 spread.save(success, error, options) 用于导出工作簿;在导出 Excel 时可通过 saveAsView 控制是否按视图导出。 saveAsView: true 用于把 SparklineEx 或类似扩展可视化内容按图片视图写入导出的 Excel 文件。
window.onload = function () { const spread = new GC.Spread.Sheets.Workbook(document.getElementById('spread-host'), { sheetCount: 2 }); document.querySelector('sjs-report-toolbar').attachSpread(spread); initSpread(spread); }; function initSpread(spread) { initSheet(spread.getSheet(0)); initSheet1(spread.getSheet(1)); } function initSheet(sheet) { const data = [ ['销售人员', '1月', '2月', '3月', '4月', '5月', '6月', '柱形迷你图'], ['张伟', 76000, 68250, 72000, 99750, 45500, 120500], ['王芳', 118750, 89250, 121250, 92500, 60750, 122750], ['李娜', 75500, 56500, 65500, 62750, 77500, 51750], ['刘洋', 76750, 108500, 88000, 55750, 106000, 75500], ['陈杰', 104500, 49000, 50250, 46750, 76750, 53250], ['赵敏', 82500, 103000, 48750, 119750, 110500, 112250], ['黄丽', 111500, 124250, 118250, 91500, 80750, 120250], ['周强', 47250, 73250, 105750, 58250, 79500, 56250], ['吴婷', 66500, 54500, 121500, 53750, 53250, 61250], ['徐磊', 108750, 96250, 72250, 85500, 51750, 68250], ] sheet.suspendPaint(); sheet.name("柱形迷你图"); sheet.setArray(2, 1, data); for (var i = 4; i < 14; i++) { sheet.setFormula(i - 1, 8, '=COLUMNSPARKLINE(C' + i + ':H' + i + ',1)'); sheet.setRowHeight(i - 1, 30); } //format sheet sheet.addSpan(0, 1, 1, 8); sheet.getCell(0, 1).value("销售数据").font("15px Arial") .backColor("#DDDDDD"); sheet.setRowHeight(0, 45); sheet.getRange(2, 1, 1, 8) .font("bold 13px Arial") .setBorder(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin), { bottom: true }); sheet.getRange(3, 2, 10, 6) .formatter("$#,##0"); for (var j = 2; j < 8; j++) { sheet.setColumnWidth(j, 80); } sheet.setColumnWidth(1, 120); sheet.setColumnWidth(8, 150); sheet.getRange(0, 0, 15, 9).vAlign(GC.Spread.Sheets.VerticalAlign.center); sheet.resumePaint(); }; function initSheet1(sheet) { sheet.suspendPaint(); sheet.name('条码'); _setData(sheet); _setStyle(sheet); var FORMULA = 'BC_CODE128'; for (var row = 3; row < 7; row++) { sheet.setFormula(row, 3, '=' + FORMULA + '(C' + (row + 1) + ')'); sheet.setFormula(row, 4, '=' + FORMULA + '(C' + (row + 1) + ', , , false)'); sheet.setFormula(row, 5, '=' + FORMULA + '(C' + (row + 1) + ', , , true, "top", "B","Arial", "normal")'); } sheet.resumePaint(); } function _setData(sheet) { sheet.getCell(1, 1).value('服务'); sheet.getCell(1, 2).value('号码'); sheet.getCell(1, 3).value('Code128'); sheet.getCell(2, 3).value('默认'); sheet.getCell(2, 4).value('隐藏标签'); sheet.getCell(2, 5).value('自定义标签字体'); var dataArray = [ ['报警服务', 911], ['电话查号服务', 411], ['市政非紧急服务', 311], ['出行信息服务 511', 511] ]; sheet.setArray(3, 1, dataArray); } function _setStyle(sheet) { for (var row = 3; row < 7; row++) { sheet.setRowHeight(row, 80); } sheet.addSpan(1, 1, 2, 1) sheet.addSpan(1, 2, 2, 1) sheet.addSpan(1, 3, 1, 3) sheet.setColumnWidth(0, 20); sheet.setColumnWidth(1, 240); sheet.setColumnWidth(2, 100); sheet.setColumnWidth(3, 240); sheet.setColumnWidth(4, 240); sheet.setColumnWidth(5, 240); sheet.getRange(1, 1, 2, 5) .foreColor('#000') .backColor('#FFF3CE') .borderLeft(new GC.Spread.Sheets.LineBorder('orange', GC.Spread.Sheets.LineStyle.thin), { outline: true }) .borderBottom(new GC.Spread.Sheets.LineBorder('orange', GC.Spread.Sheets.LineStyle.thin), { outline: true }); sheet .getRange(1, 1, 6, 5) .vAlign(GC.Spread.Sheets.VerticalAlign.center) .hAlign(GC.Spread.Sheets.HorizontalAlign.center) .setBorder(new GC.Spread.Sheets.LineBorder('orange', GC.Spread.Sheets.LineStyle.medium), { outline: true }); }
<!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" /> <meta name="spreadjs culture" content="zh-cn" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <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-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-shapes/dist/gc.spread.sheets.shapes.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-barcode/dist/gc.spread.sheets.barcode.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/sample/features/sparklines/export-sparkline-ex-to-image/toolbar.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 class="sample-tutorial"> <sjs-report-toolbar></sjs-report-toolbar> <div id="spread-host"></div> </div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } #spread-host { width: 100%; height: calc(100% - 56px); overflow: hidden; float: left; }