前端集成报表设计器—高效搞定报表设计

引言
前端框架Vue.js是当下前端开发非常喜欢的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的。相比于其他库,Vue.js提供了更加简洁、更易于理解的API,使得我们能够快上手并使用Vue.js
Vue这么受大家的喜爱,那么有没有一款好的在 线报表设计器 可以直接跟Vue集成了?现在任何项目报表不部分都是一个不可或缺的模块,以前设计报表都是让研发人员或者专业的报表设计人员进行报表设计,后期项目中要进行 报表编辑、报表添加 都需要专业的人员编辑好报表,然后再上传到服务器上进行发布。整个流程操作流程繁琐,并且时效性不是很好。特别不适合当下的SAAS应用或者是那种报表数量多并且改动频率比较多的系统。那么遇到这种问题,最好的办法就是直接把 设计器 集成到项目中,让最终系统使用者可以在线进行报表的编辑或者设计。俗话说授人以鱼不如授人以渔、现在我提供给你一个系统,系统中还自带了报表设计器,并附带报表设计操作教程,给整个系统使用者进行数据赋能,最终得到一个双赢的效果。
ActiveReportsJS包含两个设计器,桌面端设计器和web端设计器。在实际的报表系统中有报表编辑和创建的需求, 那么就可以根据自己的需求把web端在线设计器集成到报表系统中,实现报表的新增、编辑的需求。
下面我们就来讲解下,如何创建一个web端在线设计器
1、创建Vue引用
创建 Vue 应用的最简单的方法是使用Vue CLI
vue create -p default webonline
2、安装 ActiveReportsJS 相关文件
Web 报表设计器功能是放在@grapecity/activereports-vue NPM 包中,@grapecity/activereports npm 包中存放核心功能。在使用 ActiveReportsJS 时,可以执行以下命令来安装在应用根目录下:
npm install @grapecity/activereports-vue @grapecity/activereports
或者使用yarn命令
yarn add @grapecity/activereports-vue @grapecity/activereports
如果您使用的是 Vue 2.0, 需要安装@vue/composition-api 包:
npm install @vue/composition-api
或
yarn add @vue/composition-api
3、将 ActiveReportsJS报表添加到应用程序
ActiveReportsJS 使用 JSON格式和rdlx-json扩展用于报表模板文件。在应用程序的public文件夹下,创建名为report.rdlx-json的新文件,并在该文件中插入以下JSON内容。
{
"Name": "Report",
"Body": {
"ReportItems": [
{
"Type": "textbox",
"Name": "TextBox1",
"Value": "Hello, ActiveReportsJS Designer",
"Style": {
"FontSize": "18pt"
},
"Width": "8.5in",
"Height": "0.5in"
}
]
}
}
添加设计器宿主元素
打开 src\App.vue 文件,添加代码如下,单文件组件 调用 Vue 报表设计器来加载上一步骤创建的报表模板
<template>
<div id="designer-host">
<JSDesigner v-bind:report="{id: 'report.rdlx-json', displayName: 'my report' }"></JSDesigner>
</div>
</template>
<script>
import { Designer } from "@grapecity/activereports-vue";
export default {
name: "App",
components: {
JSDesigner: Designer,
},
};
</script>
<style src="https://my.oschina.net/powertoolsteam/node_modules/@grapecity/activereports/styles/ar-js-ui.css"></style>
<style src="../node_modules/@grapecity/activereports/styles/ar-js-designer.css" ></style>
<style>
#designer-host {
width: 100%;
height: 100vh;
}
</style>
4、运行项目

5、给Web端在线设计器添加保存,预览的功能
<template>
<div>
<div id="designer-toolbar" class="container-fluid">
<div class="row mt-3 mb-3">
<button type="button"
class="btn btn-secondary btn-sm col-sm-2 ml-1"
v-on:click="onDesignerOpen()"
:style="{display: designerHidden ? 'block' : 'none'}">
打开设计器
</button>
</div>
</div>
<div id="viewer-host" :style="{display: designerHidden ? 'block' : 'none'}"><ReportViewer ref="reportViewer" /></div>
<div id="designer-host"></div>
<div class="modal" id="dlgOpen" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Open Report</h5>
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h2>Select Report:</h2>
<div class="list-group">
<button type="button"
class="list-group-item list-group-item-action"
v-for="reportId in reportIds"
v-on:click="onSelectReport(reportId)"
:key="reportId">
{{reportId}}
</button>
</div>
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-secondary"
data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
// 报表设计器包
import { Designer as ReportDesigner } from "@grapecity/activereports/reportdesigner";
import "@grapecity/activereports-localization/dist/designer/zh-locale"; // 中文包
import "@grapecity/activereports-localization";
import "@grapecity/activereports/styles/ar-js-designer.css";
// 报表查看器包
import { Viewer } from "@grapecity/activereports-vue";
import "@grapecity/activereports/styles/ar-js-viewer.css";
// 设计器与查看器公用包
import "@grapecity/activereports/styles/ar-js-ui.css";
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
import "../../node_modules/bootstrap/dist/js/bootstrap.min.js";
import $ from "jquery";
let resolveFunc = null;
export default {
name: "Report",
components: {
ReportViewer: Viewer,
},
data() {
return {
reportStorage: new Map(),
reportIds: null,
counter: 0,
designer: null, // 设计器实例
designerHidden: false, // 显示隐藏设计器
disableOpenSaveHotkeys: true,
// 初始化报表查看器参数
reportTemplate: {
Type: "report",
Body: {
Name: "Body",
Type: "section",
ReportItems: [
{
Type: "textbox",
Name: "textbox1",
Style: {
FontSize: "18pt",
},
Value: "Hello, ActiveReportsJS Viewer",
Height: "10in",
},
],
},
Name: "Report",
},
};
},
methods: {
onDesignerOpen() {
this.designerHidden = false;
},
onSelectReport(reportId) {
if (resolveFunc) {
alert("1");
$("#dlgOpen").modal("hide");
resolveFunc({ definition: this.reportStorage.get(reportId), id: reportId, displayName: reportId });
resolveFunc = null;
}
},
},
mounted() {
const _this = this;
this.designer = new ReportDesigner("#designer-host", {
language: "zh", //汉化;
}); // 初始化报表设计器
this.designer.setActionHandlers({
// 添加预览功能
onRender: async (report) => {
this.designerHidden = true;
console.log(report);
this.$refs.reportViewer.Viewer().open(report.definition);
return Promise.resolve();
},
// 添加保存功能
onSave: (info) => {
const reportId = info.id || `NewReport${_this.counter + 1}`;
_this.reportStorage.set(reportId, info.definition);
_this.counter++;
return Promise.resolve({ displayName: reportId });
},
// 添加另存为功能
onSaveAs: function (info) {
const reportId = `NewReport${_this.counter + 1}`;
_this.reportStorage.set(reportId, info.definition);
_this.counter++;
return Promise.resolve({ id: reportId, displayName: reportId });
},
onOpen: function () {
const ret = new Promise(function (resolve) {
resolveFunc = resolve;
_this.reportIds = _this.reportStorage.keys();
$("#dlgOpen").modal("show");
});
return ret;
},
});
},
};
</script>
<style>
#designer-host, #viewer-host {
width: 100%;
height: 800px;
}
</style>
6、预览结果

7、前端报表示例展示







</div>