概述
本示例展示了如何在 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;
}