1、放在public下面,开始用下面的,会报错,找不到相应的js文件,
<!-- luckysheet for bigscreen -->
<link rel='stylesheet' href='./luckysheet/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='./luckysheet/plugins/plugins.css' />
<link rel='stylesheet' href='./luckysheet/css/luckysheet.css' />
<script src="./luckysheet/plugins/js/plugin.js"></script>
<script src="./luckysheet/luckysheet.umd.js"></script>
2、后来修改如下:
<!-- luckysheet for bigscreen -->
<link rel='stylesheet' href='<%= BASE_URL %>luckysheet/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='<%= BASE_URL %>luckysheet/plugins/plugins.css' />
<link rel='stylesheet' href='<%= BASE_URL %>luckysheet/css/luckysheet.css' />
<script src="<%= BASE_URL %>luckysheet/plugins/js/plugin.js"></script>
<script src="<%= BASE_URL %>luckysheet/luckysheet.umd.js"></script>
3、上面好了后,出现下面问题
4、需要在luckysheet.umd.js 这个文件的引入chartmix进行修改,以后发布生产也要修改了,这个就比较麻烦了,以后生成还要修改成生产的,以后考虑从luckysheet源代码生成修改吧。
5、这样就正常了,可以进行图表的展示了,如下:
6、后来发现上面的保存与预览的图标没有显示,这个是iconfont方式,应该是没有引入对,后来检查了 检查了designer的index文件,正确引入下面文件就正常了
<style src="@/assets/bs/iconfont/iconfont.css" />
7、编辑连接数据集,如下图,不过有问题浏览器兼容性还没做好,我用qq浏览器就不行,不能拖拉进去,用谷歌与edge是都可以。
8、预览如下:
9、报表设计页面代码
<!--
* @Author: lide1202@hotmail.com
* @Date: 2021-3-13 11:04:24
* @Last Modified by: nbacheng
* @Last Modified time: 2023-09-09
!-->
<template>
<div class="layout">
<div class="layout-left">
<div class="add-collection">
数据集管理
<el-button
type="text"
icon="el-icon-circle-plus-outline"
@click="queryAllDataSet()"
/>
</div>
<div>
<el-collapse
v-for="(item, indexs) in dataSet"
:key="indexs"
v-model="activeNames"
@change="handleChange"
>
<el-collapse-item :title="item.setName" :name="item.id">
<el-popconfirm
:title="'确定删除' + item.setName + '吗?'"
@confirm="del(item)"
>
<el-button
slot="reference"
type="text"
icon="el-icon-close"
class="delect-all"
/>
</el-popconfirm>
<draggable
v-model="item.setParamList"
:sort="false"
group="people"
style="margin-left: 10px"
@start="onStart(item.setCode, $event)"
>
<!-- <transition-group> -->
<div
v-for="(i, index) in item.setParamList"
:key="index"
class="field-container"
>
<div class="aRow">
<span>{{ i }}</span>
</div>
</div>
<!-- </transition-group> -->
</draggable>
</el-collapse-item>
</el-collapse>
</div>
</div>
<div class="layout-middle">
<div class="push_btn">
<el-tooltip
class="item"
effect="dark"
content="预览"
placement="bottom-start"
>
<el-button type="text" @click="preview()">
<i class="iconfont iconfuzhi"></i>
</el-button>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="保存"
placement="bottom-start"
>
<el-button type="text" @click="save()">
<i class="iconfont iconsave"></i>
</el-button>
</el-tooltip>
</div>
<div
id="luckysheet"
style="margin:0px;padding:0px;position:absolute;width:100%;height:95vh;left: 0px;top: 30px;bottom:0px;"
/>
<div id="qrCode" ref="qrCodeDiv" />
<img id="barCode" />
</div>
<div class="layout-right">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="基础配置" name="first">
<el-form ref="rightForm" :model="rightForm" label-width="70px">
<el-form-item label="坐标">
<el-input v-model="rightForm.coordinate" />
</el-form-item>
<el-form-item label="值">
<el-input v-model="rightForm.value" />
</el-form-item>
<el-form-item label="自动扩展" v-if="rightForm.autoIsShow">
<el-col :span="12">
<el-switch
v-model="rightForm.auto"
@change="autoChangeFunc($event)" />
</el-col>
<el-col :span="12">
<el-tooltip class="item" effect="dark" content="只针对静态数据的单元格,具体参考文档" placement="top">
<i class="el-icon-question"> </i>
</el-tooltip>
</el-col>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</div>
<el-dialog title="数据集管理" :visible.sync="outerVisible">
<el-table
ref="multipleTable"
:data="dataSetData"
tooltip-effect="dark"
style="width: 100%;height: 60vh;overflow-y: scroll;"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="数据集名称" width="120" prop="setName" />
<el-table-column prop="setDesc" label="数据集描述" width="180" />
<el-table-column
prop="setCode"
label="数据集编码"
show-overflow-tooltip
/>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="outerVisible = false">取 消</el-button>
<el-button type="primary" @click="checkDataSet()">确定 </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import draggable from "vuedraggable";
import { queryAllDataSet, detail, detailByReportCode } from "@/api/bigscreen/excelreport";
import { addReportExcel, editReportExcel } from "@/api/bigscreen/excelreport";
import ColorPicker from "../components/colorPicker.vue";
// import QRCode from 'qrcodejs2'
// import JsBarcode from 'jsbarcode'
export default {
name: "Excels",
components: {
draggable,
ColorPicker
},
data() {
return {
activeName: "first",
activeNames: ["1"],
reportId: null,
accessKey: null,
reportCode: "",
options: [],
sheet: {},
sheetData: [],
dataSetData: [],
reportExcelDto: {
id: null,
jsonStr: "",
setCodes: "",
setParam: "",
reportCode: ""
},
multipleSelection: [],
rightForm: {
coordinate: "",
value: "",
r: "",
c: "",
auto: false,
autoIsShow: false
},
qrCodeForm: {
type: "QRCode",
content: "https://www.baidu.com",
width: 125,
height: 125,
colorDark: "#333333", // 二维码颜色
colorLight: "#ffffff", // 二维码背景色
// correctLevel: QRCode.CorrectLevel.L, // 容错率,L/M/H
ri: 0,
ci: 0,
currentSrc: ""
},
barCodeForm: {
type: "BarCode",
format: "CODE39",
displayValue: true,
content: "99999999999",
lineColor: "#000",
background: "#fff",
width: 100,
height: 40,
ri: 0,
ci: 0,
currentSrc: ""
},
formPrintSetting: {
size: "",
pixel1: "",
pixel2: ""
},
pixelList: [
{ paper: "A4", width: 210, height: 297 },
{ paper: "A3", width: 297, height: 420 },
{ paper: "Letter", width: 216, height: 279 },
{ paper: "Legal", width: 216, height: 355 },
{ paper: "Executive", width: 184, height: 266 }
],
dataSet: [],
outerVisible: false,
printVisible: false,
pop: false,
setCode: null,
draggableFieldLabel: null,
dialogVisible: false,
dialogBarCode: false,
paperList: [],
// 纸张标识
paper: "",
// 纸张宽高
width: "",
height: "",
// 清晰度
definition: "",
// 是否套打
isBackend: "",
dpi: "",
pxWidth: "",
pxHeight: "",
show: false,
config: "",
settings: {},
qrCodeList: [],
moveDataelse: {
x: null,
y: null
}
};
},
mounted() {},
created() {
this.reportCode = this.$route.query.reportCode;
this.accessKey = this.$route.query.accessKey;
this.loadDataSet();
this.design();
},
methods: {
handleClose() {
this.printVisible = false;
},
handleChange(val) {},
// 右侧信息配置tabs
handleClick(tab, event) {},
async design() {
// 根据reportCode获取单条报表
const { code, result } = await detailByReportCode(this.reportCode);
if (result != null) {
this.reportId = result.id;
}
console.log("result=",result);
console.log("this.sheetData=",this.sheetData);
this.sheetData = result == null ? [{}] : JSON.parse(result.jsonStr);
console.log("this.sheetData=",this.sheetData);
this.createSheet();
if (result != null) {
if (result.setCodes != null && result.setCodes !== "") {
let dataSetList = result.setCodes.split("|");
dataSetList.forEach(code => {
this.dataSetData.forEach(setData => {
if (code === setData.setCode) {
this.detail(setData.id);
}
});
});
}
}
},
//初始化表格
createSheet() {
//将vue对象传入
const that = this;
const options = {
container: "luckysheet", // 设定DOM容器的id
title: "", // 设定表格名称
lang: "zh", // 设定表格语言
plugins: ["chart"],
hook: {
cellDragStop: function(cell, postion, sheetFile, ctx, event) {
// console.info("cellDragStop-cell",cell);
// console.info("cellDragStop-postion", postion);
// console.info("cellDragStop-sheetFile", sheetFile);
// console.info("cellDragStop-ctx",ctx);
// console.info("cellDragStop-event", event);
// console.log("cellDragStop-draggableFieldLabel", that);
luckysheet.setCellValue(
postion.r,
postion.c,
that.draggableFieldLabel
);
},
cellMousedown: function(cell, postion, sheetFile, ctx) {
//单元格点击事件
that.rightForm.coordinate = postion.r + "," + postion.c;
that.rightForm.r = postion.r;
that.rightForm.c = postion.c;
that.rightForm.value = cell == null ? "" : cell.v;
that.rightForm.autoIsShow = true
//判断单元格是否是静态数据并且是合并单元格
if(cell != null && ( cell.v == undefined || cell.v.indexOf('#{') === -1)){
that.rightForm.autoIsShow = true
if(cell.auto != null && cell.auto == '1'){
that.rightForm.auto = true
}else{
that.rightForm.auto = false
}
}else{
that.rightForm.auto = false
}
}
},
data: [
{
name: "report", //工作表名称
color: "", //工作表颜色
index: 0, //工作表索引
status: 1, //激活状态
order: 0, //工作表的下标
hide: 0, //是否隐藏
row: 36, //行数
column: 18, //列数
defaultRowHeight: 19, //自定义行高
defaultColWidth: 73, //自定义列宽
celldata: [], //初始化使用的单元格数据
config: {
merge: {}, //合并单元格
rowlen: {}, //表格行高
columnlen: {}, //表格列宽
rowhidden: {}, //隐藏行
colhidden: {}, //隐藏列
borderInfo: {}, //边框
authority: {} //工作表保护
},
scrollLeft: 0, //左右滚动条位置
scrollTop: 315, //上下滚动条位置
luckysheet_select_save: [], //选中的区域
calcChain: [], //公式链
isPivotTable: false, //是否数据透视表
pivotTable: {}, //数据透视表设置
filter_select: {}, //筛选范围
filter: null, //筛选配置
luckysheet_alternateformat_save: [], //交替颜色
luckysheet_alternateformat_save_modelCustom: [], //自定义交替颜色
luckysheet_conditionformat_save: {}, //条件格式
frozen: {}, //冻结行列配置
chart: [], //图表配置
zoomRatio: 1, // 缩放比例
image: [], //图片
showGridLines: 1, //是否显示网格线
dataVerification: {} //数据验证配置
}
]
};
options.data = this.sheetData;
$(function() {
luckysheet.create(options);
});
},
onStart(setCode, evt) {
this.setCode = setCode;
let fieldLabel = evt.item.innerText; // 列名称
this.draggableFieldLabel = "#{" + this.setCode + "." + fieldLabel + "}";
console.log("evt", evt);
console.log("draggableFieldLabel", this.draggableFieldLabel);
},
async loadDataSet() {
const { code, result } = await queryAllDataSet();
this.dataSetData = result;
if (code != "200") return;
},
doCancel() {
this.pop = false;
},
async save() {
// console.log(luckysheet.toJson())
// console.log(luckysheet.getAllSheets())
// console.log(luckysheet.getSheetData(0))
const jsonData = luckysheet.getAllSheets();
for (let i = 0; i < jsonData.length; i++) {
//清空data数据,以celldata数据为主
jsonData[i]["data"] = [];
}
this.reportExcelDto.jsonStr = JSON.stringify(luckysheet.getAllSheets());
let setCodeList = [];
let setParams = {};
this.dataSet.forEach(code => {
setCodeList.push(code.setCode);
if (
code.dataSetParamDtoList != null &&
code.dataSetParamDtoList.length > 0
) {
let dataSetParam = {};
code.dataSetParamDtoList.forEach(value => {
dataSetParam[value.paramName] = value.sampleItem;
});
setParams[code.setCode] = dataSetParam;
}
});
this.reportExcelDto.setParam = JSON.stringify(setParams);
this.reportExcelDto.setCodes = setCodeList.join("|");
this.reportExcelDto.reportCode = this.reportCode;
if (this.reportId == null) {
const { code } = await addReportExcel(this.reportExcelDto);
if (code != "200") return;
this.$message.success("保存成功");
} else {
this.reportExcelDto.id = this.reportId;
const { code } = await editReportExcel(this.reportExcelDto);
if (code != "200") return;
this.$message.success("更新成功");
}
},
async detailByReportCode(reportCode) {
const { code, result } = await detailByReportCode(reportCode);
if (result != null) {
this.reportId = result.id;
}
},
async preview() {
let routeUrl = this.$router.resolve({
path: "/excelreport/viewer",
query: { reportCode: this.reportCode }
});
window.open(routeUrl.href, "_blank");
},
async queryAllDataSet() {
this.outerVisible = true;
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
checkDataSet() {
this.outerVisible = false;
if (this.multipleSelection.length > 1) {
this.$message({
message: "一次最多勾选一个数据集",
type: "warning"
});
this.outerVisible = true;
} else {
this.detail(this.multipleSelection[0].id);
}
},
async detail(id) {
const { code, result } = await detail(id);
if (code != 200) return;
let flag = true;
this.dataSet.forEach(value => {
if (value.setCode === result.setCode) {
flag = false;
}
});
if (flag) {
this.dataSet.push(result);
}
},
del(val) {
for (let i = 0; i < this.dataSet.length; i++) {
if (this.dataSet[i].setCode === val.setCode) {
this.dataSet.splice(i, 1);
}
}
},
autoChangeFunc(auto){
if(auto){
luckysheet.setCellValue(this.rightForm.r, this.rightForm.c, { auto: "1"})
}else{
luckysheet.setCellValue(this.rightForm.r, this.rightForm.c, { auto: "0"})
}
}
}
};
</script>
<style src="@/assets/bs/iconfont/iconfont.css" />
<style scoped lang="scss">
.position {
position: absolute;
z-index: 100;
}
#qrCode,
#barCode {
display: none;
}
.yulancopy {
font-size: 16px;
}
.baocun {
font-size: 17px;
}
.el-collapse {
position: relative;
border-top: 0 solid #e6ebf5;
border-bottom: 0 solid #e6ebf5;
}
.el-collapse-item__header {
border-bottom: 0 solid #e6ebf5 !important;
}
.delect-all {
position: absolute;
top: 10px;
right: 30px;
color: #333;
}
.push_btn {
position: absolute;
z-index: 100;
top: 5px;
left: 3px;
.iconfont {
color: black;
}
}
.add-collection {
line-height: 30px;
.el-button {
font-size: 16px !important;
vertical-align: middle;
margin-left: 20px;
}
}
.layout {
display: block;
position: relative;
margin: 0;
padding: 0;
border: 1px solid #d7dde4;
}
.layout-left {
display: block;
position: absolute;
padding: 20px;
width: 230px;
min-height: 99.98vh;
border-right: 1px solid #eee;
border-color: #e8eaec;
background: #fff;
border-radius: 4px;
font-size: 14px;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
top: 0;
left: 0;
.field-container {
display: block;
position: relative;
width: 100%;
margin: 0;
cursor: pointer;
line-height: 30px;
.aRow {
padding: 0 10px;
.operation {
float: right;
display: none;
.el-button--text {
color: #333 !important;
}
}
&:hover {
.operation {
display: block;
}
background: #f7fafd;
}
}
}
}
.layout-middle {
display: block;
position: absolute;
left: 230px;
right: 230px;
width: calc(100% - 460px);
margin: 0;
padding: 0;
.excel-designer {
display: block;
position: relative;
margin: 0;
padding: 0;
}
}
.layout-right {
display: block;
position: absolute;
top: 0;
right: 0;
padding: 20px;
width: 230px;
min-height: 99.98vh;
border-left: 1px solid #dcdee2;
border-color: #e8eaec;
background: #fff;
border-radius: 4px;
font-size: 14px;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
</style>
10、viewer代码如下:
<!--
* @Author: lide1202@hotmail.com
* @Date: 2021-3-13 11:04:24
* @Last Modified by: nbacheng
* @Last Modified time: 2023-09-09
!-->
<template>
<div class="layout">
<div class="layout-right">
<div class="block">
<div class="download">
<a v-if="reportCode != null" download="xxx.xlsx">
<el-button type="text" @click="download('gaea_template_excel')">
<i class="iconfont iconexcel"></i>导出excel
</el-button>
</a>
<a v-if="reportCode != null" download="xxx.pdf">
<el-button type="text" @click="download('gaea_template_pdf')">
<i class="iconfont iconpdf"></i>导出pdf
</el-button>
</a>
</div>
<el-form class="">
<h2>表格查询</h2>
<div v-for="(item, num) in tableData2" :key="num + 'excel'">
<h4>{{ item.name }}</h4>
<div
v-for="(son, y) in item.children"
:key="y + 'excel2'"
class="search_input"
>
<label>{{ son.name }}:</label>
<el-input v-model="son.value" />
</div>
</div>
<el-button style="width: 100%" @click="searchPreview">查询</el-button>
</el-form>
<!--<el-pagination :current-page="currentPage4" :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="total, sizes, prev, pager, next, jumper" :total="400" @size-change="handleSizeChange" @current-change="handleCurrentChange" />-->
</div>
</div>
<div class="layout-middle">
<div
id="luckysheet"
style="margin:0px;padding:0px;position:absolute;width:100%;height:95vh;left: 0px;top: 30px;bottom:0px;"
/>
</div>
</div>
</template>
<script>
import { preview, exportExcel } from "@/api/bigscreen/excelreport";
export default {
name: "Login",
components: {},
data() {
return {
options: {},
sheet: {},
reportId: null,
reportCode: null,
reportName: null,
dataSet: null,
tableData2: [],
excelData: {},
params: {
reportCode: "",
setParam: ""
}
};
},
mounted() {
this.preview();
},
created() {
this.reportCode = this.$route.query.reportCode;
},
methods: {
async searchPreview() {
const arr = this.toObject(this.tableData2);
this.params.setParam = JSON.stringify(arr);
//每次都重新加载需要改成刷新
this.preview();
},
async preview() {
this.excelData = {};
this.params.reportCode = this.reportCode;
const { code, result } = await preview(this.params);
if (code != 200) return;
this.reportName = JSON.parse(result.jsonStr).name;
// 渲染查询表单
this.params.setParam = JSON.parse(result.setParam);
const extendArry = [];
const extendObj = this.params.setParam;
for (const i in extendObj) {
const children = [];
for (const y in extendObj[i]) {
children.push({ name: y, value: extendObj[i][y] });
}
extendArry.push({ name: i, children: children });
}
this.tableData2 = extendArry;
this.excelData = result.jsonStr;
this.sheetData = result == null ? [{}] : JSON.parse(result.jsonStr);
// console.log(this.excelData)
// console.log(this.sheetData)
this.createSheet();
},
async download(val) {
if (val == "gaea_template_pdf") {
this.$message("暂不支持pdf");
return;
}
const result = {};
result["reportCode"] = this.reportCode;
result["setParam"] = JSON.stringify(this.params.setParam);
if (val != "") {
result["exportType"] = val;
}
const { code, message } = await exportExcel(result);
if (code != 200) return;
this.$message.success(message);
},
// 表单封装json
toObject(val) {
const objfirst = {};
const objSecond = {};
val.forEach(el => {
el.name ? (objfirst[el.name] = el.children) : "";
});
for (const key in objfirst) {
const newObj = {};
objfirst[key].map(ev => {
Object.assign(newObj, { [ev.name]: ev.value });
});
objSecond[key] = newObj;
}
return objSecond;
},
//初始化表格
createSheet() {
const options = {
container: "luckysheet", // 设定DOM容器的id
title: "", // 设定表格名称
lang: "zh", // 设定表格语言
plugins: ["chart"],
data: [
{
name: "report", //工作表名称
color: "", //工作表颜色
index: 0, //工作表索引
status: 1, //激活状态
order: 0, //工作表的下标
hide: 0, //是否隐藏
row: 36, //行数
column: 18, //列数
defaultRowHeight: 19, //自定义行高
defaultColWidth: 73, //自定义列宽
celldata: [], //初始化使用的单元格数据
config: {
merge: {}, //合并单元格
rowlen: {}, //表格行高
columnlen: {}, //表格列宽
rowhidden: {}, //隐藏行
colhidden: {}, //隐藏列
borderInfo: {}, //边框
authority: {} //工作表保护
},
scrollLeft: 0, //左右滚动条位置
scrollTop: 315, //上下滚动条位置
luckysheet_select_save: [], //选中的区域
calcChain: [], //公式链
isPivotTable: false, //是否数据透视表
pivotTable: {}, //数据透视表设置
filter_select: {}, //筛选范围
filter: null, //筛选配置
luckysheet_alternateformat_save: [], //交替颜色
luckysheet_alternateformat_save_modelCustom: [], //自定义交替颜色
luckysheet_conditionformat_save: {}, //条件格式
frozen: {}, //冻结行列配置
chart: [], //图表配置
zoomRatio: 1, // 缩放比例
image: [], //图片
showGridLines: 1, //是否显示网格线
dataVerification: {} //数据验证配置
}
]
};
options.data = this.sheetData;
// console.log(this.sheetData)
$(function() {
luckysheet.create(options);
});
}
}
};
</script>
<style src="@/assets/bs/iconfont/iconfont.css" />
<style scoped lang="scss">
.download {
width: 100%;
float: left;
button {
color: #444;
width: 90px;
text-align: left;
.svg-icon {
font-size: 16px;
margin-right: 10px;
}
}
}
.block {
position: relative;
z-index: 10000;
top: 0;
background: #fff;
width: 100%;
h2 {
font-size: 14px;
line-height: 30px;
}
h4 {
font-size: 12px;
}
.search_input {
font-size: 12px;
margin-bottom: 10px;
label {
line-height: 20px;
}
}
}
.layout {
display: block;
position: relative;
margin: 0;
padding: 0;
}
.layout-middle {
display: block;
position: absolute;
left: 200px;
right: 0;
width: calc(100% - 200px);
margin: 0;
padding: 0;
.excel-designer {
display: block;
position: relative;
margin: 0;
padding: 0;
}
}
.layout-right {
display: block;
position: absolute;
top: 0;
left: 0;
padding: 20px;
width: 200px;
min-height: 99.98vh;
border-left: 1px solid #dcdee2;
border-color: #e8eaec;
background: #fff;
border-radius: 4px;
font-size: 14px;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
</style>