report-wv.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. <link rel='stylesheet' href='../luckysheet/dist/plugins/plugins.css' />
  9. <link rel='stylesheet' href='../luckysheet/dist/plugins/css/pluginsCss.css' />
  10. <link rel='stylesheet' href='../luckysheet/dist/css/luckysheet.css' />
  11. <link rel='stylesheet' href='../luckysheet/dist/assets/iconfont/iconfont.css' />
  12. <link rel="stylesheet" href="../dist/css/layui.css">
  13. <style>
  14. .la-btn {
  15. position: absolute;
  16. left: 50%;
  17. bottom: 35px;
  18. transform: translate(-50%);
  19. padding: 0 2%;
  20. }
  21. .btn {
  22. width: 100%;
  23. }
  24. .layui-laypage-em {
  25. background-color: #1e9fff !important;
  26. }
  27. </style>
  28. </head>
  29. <body>
  30. <div id="luckysheet" style="margin:0px;padding:0px;position:absolute;width:100%;height:90%;left: 0px;top: 0px;">
  31. </div>
  32. <table id="demo" lay-filter="test"></table>
  33. <div class="la-btn">
  34. <button id="recordBtn" type="button" class="layui-btn layui-btn-normal layui-btn-sm btn">运行记录</button>
  35. </div>
  36. <script src="../jquery.min.js"></script>
  37. <script src="../dist/layui.js"></script>
  38. <script src="../luckysheet/dist/luckysheet.umd.js"></script>
  39. <script src="../luckysheet/dist/plugins/js/plugin.js"></script>
  40. <script src="./echarts.js"></script>
  41. <!-- uni 的 SDK -->
  42. <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
  43. <script>
  44. $(function() {
  45. document.addEventListener('UniAppJSBridgeReady', function() {
  46. uni.getEnv(function(res) {
  47. console.log('当前环境:' + JSON.stringify(res));
  48. const id = window.location.search.split('?id=')[1]
  49. $.ajax({
  50. url: "http://192.168.0.40:8081/reportTable/getReportTableById/" + id,
  51. type: 'GET',
  52. success: function(res) {
  53. if (res.code === 200) {
  54. console.log(res.data, 'res.data');
  55. // 报表数据
  56. let tableData = JSON.parse(res.data.reportTableData)
  57. let option = tableData.option
  58. console.log(tableData, 'jsonData')
  59. // 基础数据项值
  60. let baseItem = tableData.baseItem
  61. // 数据项
  62. let reportTableItemList = res.data.reportTableItemList
  63. let reportChartList = res.data.reportChartList
  64. // 报表类型
  65. let reportTableType = res.data.reportTableType
  66. drawTableData(reportTableItemList, reportTableType)
  67. let luckysheetOption = {
  68. container: 'luckysheet', // 设定 DOM 容器的 id
  69. title: '报表模板', // 设定表格名称
  70. lang: 'zh', // 设定表格语言
  71. showinfobar: false, // 是否显示顶部信息栏
  72. showtoolbar: false, // 是否显示工具栏
  73. showtoolbarConfig: {
  74. paintFormat: true, //格式刷
  75. moreFormats: true, // 单元格格式
  76. font: true, // 字体
  77. fontSize: true, // 字号大小
  78. bold: true, // 粗体 (Ctrl+B)
  79. italic: true, // 斜体 (Ctrl+I)
  80. strikethrough: true, // 删除线 (Alt+Shift+5)
  81. underline: true, // 下划线 (Alt+Shift+6)
  82. textColor: true, // 文本颜色
  83. fillColor: true, // 单元格颜色
  84. border: true, // 边框
  85. mergeCell: true, // 合并单元格
  86. horizontalAlignMode: true, // 水平对齐方式
  87. verticalAlignMode: true, // 垂直对齐方式
  88. function: true, // 公式
  89. // image: true
  90. // chart: true
  91. },
  92. showsheetbar: false, // 是否显示底部 sheet 页按钮
  93. sheetFormulaBar: false, // 是否显示公式
  94. row: 120, // 是否显示底部 sheet 页按钮
  95. data: [{
  96. "name": "统计报表", //工作表名称
  97. }],
  98. cellRightClickConfig: { // 自定义配置单元格右击菜单
  99. copy: true, // 复制
  100. copyAs: false, // 复制为
  101. paste: true, // 粘贴
  102. insertRow: true, // 插入行
  103. insertColumn: true, // 插入列
  104. deleteRow: true, // 删除选中行
  105. deleteColumn: true, // 删除选中列
  106. deleteCell: false, // 删除单元格
  107. hideRow: false, // 隐藏选中行和显示选中行
  108. hideColumn: false, // 隐藏选中列和显示选中列
  109. rowHeight: true, // 行高
  110. columnWidth: true, // 列宽
  111. clear: false, // 清除内容
  112. matrix: false, // 矩阵操作选区
  113. sort: false, // 排序选区
  114. filter: false, // 筛选选区
  115. chart: true, // 图表生成
  116. image: false, // 插入图片
  117. link: false, // 插入链接
  118. data: false, // 数据验证
  119. cellFormat: false // 设置单元格格式
  120. },
  121. plugins: ['chart']
  122. }
  123. if (!option) {
  124. option = JSON.parse(JSON.stringify(luckysheetOption))
  125. }
  126. option.data = tableData.data
  127. // 设置工作表保护
  128. option.data[0].config.authority = {
  129. sheet: 1, // 如果为 1 或 true,则该工作表受到保护;如果为 0 或 false,则该工作表不受保护。
  130. hintText: '该工作表受到保护,无法操作', // 弹窗提示的文字
  131. }
  132. // 关闭右键菜单
  133. option.cellRightClickConfig.chart = false
  134. option.cellRightClickConfig.columnWidth = false
  135. option.cellRightClickConfig.rowHeight = false
  136. option.cellRightClickConfig.deleteColumn = false
  137. option.cellRightClickConfig.deleteRow = false
  138. option.cellRightClickConfig.insertColumn = false
  139. option.cellRightClickConfig.insertRow = false
  140. // 关闭工具栏
  141. option.showtoolbar = false
  142. option.enableAddRow = false
  143. option.showtoolbarConfig = {
  144. bold: false,
  145. border: false,
  146. fillColor: false,
  147. font: false,
  148. fontSize: false,
  149. function: false,
  150. horizontalAlignMode: false,
  151. italic: false,
  152. mergeCell: false,
  153. moreFormats: false,
  154. paintFormat: false,
  155. strikethrough: false,
  156. textColor: false,
  157. underline: false,
  158. verticalAlignMode: false
  159. }
  160. // 钩子函数
  161. option.hook = {
  162. workbookCreateAfter() {
  163. // 图表操作
  164. for (let i in reportChartList) {
  165. insertEChartInfo(reportChartList[i])
  166. }
  167. // option.data.forEach((data, i) => {
  168. // if (data.chart && data.chart.length > 0) {
  169. // data.chart.forEach((chart, j) => {
  170. // console.log(chart.chart_id)
  171. // let dom = document.getElementById(chart.chart_id + '_c')
  172. // if (dom) dom.style.display = 'none'
  173. // })
  174. // }
  175. // })
  176. // 绘制基础数据项
  177. drawBaseInfo(baseItem)
  178. // 绘制数据值
  179. drawTableData(reportTableItemList,
  180. reportTableType)
  181. printExcel()
  182. luckysheet.setRangeShow('BH1')
  183. }
  184. }
  185. luckysheet.create(option)
  186. } else {
  187. layer.msg(res.msg);
  188. }
  189. }
  190. })
  191. function printExcel() {
  192. let currentSelected = luckysheet.getRange()
  193. luckysheet.hideGridLines()
  194. // 如果当前选中区只是一个单元格,则认为选取无效。
  195. if (currentSelected[0] != null &&
  196. (currentSelected[0].row[1] - currentSelected[0].row[0] >= 1 ||
  197. currentSelected[0].column[1] - currentSelected[0].column[0] >= 1)) {
  198. // 生成base64图片
  199. let imgSrc = luckysheet.getScreenshot();
  200. luckysheet.showGridLines();
  201. } else {
  202. // 获取打印区域的行列
  203. let RowColumn = getPrintSheetArea();
  204. // 因需要打印左边的边框,需重新设置第一列
  205. RowColumn.column[0] = 0;
  206. // 进行选区操作
  207. luckysheet.setRangeShow("A1:L40");
  208. let imgSrc = luckysheet.getScreenshot(); // 生成base64图片
  209. luckysheet.showGridLines();
  210. console.log(imgSrc);
  211. }
  212. }
  213. // top.window.document.write(imgSrc)
  214. // $.ajax({
  215. // url: "localhost:8084?file="+imgSrc,
  216. // type: 'GET',
  217. // success: function(res) {
  218. // }
  219. // })
  220. function getPrintSheetArea() {
  221. const sheetData = luckysheet.getSheetData();
  222. let objRowColumn = {
  223. row: [0, 0], //行
  224. column: [0, 0], //列
  225. };
  226. // * item是行、index是行索引、it是一行里的一格、itemIndex是这一格在这一行里的列索引
  227. sheetData.forEach((item, index) => {
  228. //行数
  229. item.forEach((it, itemIndex) => {
  230. if (it !== null && it.v) {
  231. console.log(index, it)
  232. if (objRowColumn.row[1] < index) {
  233. objRowColumn.row[1] = index; //row第二位
  234. }
  235. if (objRowColumn.column[1] < itemIndex) {
  236. objRowColumn.column[1] =
  237. itemIndex; //column第二位
  238. }
  239. }
  240. });
  241. });
  242. return objRowColumn;
  243. }
  244. /** 绘制表格数据 */
  245. function drawTableData(tableItemList, type) {
  246. if (!tableItemList || tableItemList.length == 0) return
  247. // 事件驱动报表
  248. if (type == 2 || type == 4) {
  249. tableItemList.forEach((tableItem, i) => {
  250. let valueList = tableItem.valueList ? tableItem.valueList
  251. .split(',') : []
  252. let xAxis = tableItem.xaxis
  253. let yAxis = tableItem.yaxis
  254. if (valueList.length == 0) {
  255. luckysheet.setCellValue(xAxis, yAxis, '')
  256. } else {
  257. valueList.forEach((v, j) => {
  258. luckysheet.setCellValue(xAxis + j, yAxis,
  259. v)
  260. })
  261. }
  262. })
  263. return
  264. }
  265. }
  266. /** 绘制基础数据项布局信息 */
  267. function drawBaseInfo(baseData) {
  268. if (!baseData) return
  269. let option = luckysheet.getAllSheets()[0]
  270. option.celldata.map(item => {
  271. if (item.v.v) {
  272. item.v.v = String(item.v.v).trim()
  273. if (item.v.v.match(/\${([^}]+)}/g)) { // 替换${xxx}内部数据
  274. if (item.v.v.indexOf('${currDate}') > -1) {
  275. let val = item.v.v
  276. val = val.replace('${currDate}', baseData.currDate)
  277. luckysheet.setCellValue(item.r, item.c, val)
  278. }
  279. if (item.v.v.indexOf('${currDateTime}') > -1) {
  280. let val = item.v.v
  281. val = val.replace('${currDateTime}', baseData
  282. .currDateTime)
  283. luckysheet.setCellValue(item.r, item.c, val)
  284. }
  285. if (item.v.v.indexOf('${userName}') > -1) {
  286. let val = item.v.v
  287. val = val.replace('${userName}', baseData.userName)
  288. luckysheet.setCellValue(item.r, item.c, val)
  289. }
  290. if (item.v.v.indexOf('${winUserName}') > -1) {
  291. let val = item.v.v
  292. val = val.replace('${winUserName}', baseData
  293. .winUserName)
  294. luckysheet.setCellValue(item.r, item.c, val)
  295. }
  296. }
  297. }
  298. })
  299. }
  300. /** 向 Excel 插入图表 */
  301. function insertEChartInfo(chart) {
  302. let _self = this
  303. let info = JSON.parse(chart.standby)
  304. let reportChartItemList = chart.reportChartItemList
  305. let chartType = chart.chartType
  306. // 系列
  307. let series = info.option.series
  308. for (let i in series) {
  309. let temp = series[i]
  310. temp.data = []
  311. for (let j in reportChartItemList) {
  312. let _name = reportChartItemList[j].describe ?
  313. reportChartItemList[j].describe : reportChartItemList[j]
  314. .itemName
  315. if (chartType == 'pie') {
  316. temp.name = _name
  317. temp.data.push({
  318. 'name': _name,
  319. 'value': reportChartItemList[j].valueList
  320. })
  321. } else {
  322. let _t = []
  323. let t = reportChartItemList[i].valueList ?
  324. reportChartItemList[i].valueList.split(',') : []
  325. t.forEach((temp) => {
  326. _t.push(parseFloat(temp))
  327. })
  328. temp.data = _t
  329. }
  330. }
  331. }
  332. if (chartType != 'pie') {
  333. // x 轴
  334. let xAxis = info.option.xAxis
  335. let legend = info.option.legend
  336. // xAxis.data = []
  337. legend.data = []
  338. xAxis.data = (reportChartItemList && reportChartItemList.length >
  339. 0) ? reportChartItemList[0].dataTimeList : []
  340. // xAxis.data = xAxis.data.slice(0, 7)
  341. for (let i in reportChartItemList) {
  342. let name = reportChartItemList[i].describe ? reportChartItemList[
  343. i].describe : reportChartItemList[i].itemName
  344. // xAxis.data.push(name)
  345. legend.data.push(name)
  346. }
  347. }
  348. console.log(chartType, info)
  349. setTimeout(() => {
  350. const sheet = luckysheet.getLuckysheetfile()[0]
  351. let optionData = sheet.data
  352. try {
  353. let flag = false
  354. insertLuckysheetEChart({
  355. selector: '#luckysheet',
  356. info,
  357. sheet,
  358. optionData,
  359. echarts,
  360. luckysheet,
  361. $,
  362. _self,
  363. flag
  364. })
  365. } catch (e) {
  366. console.log(999, e == 'echarts is not defined')
  367. console.error(e)
  368. }
  369. }, 200)
  370. }
  371. $('#recordBtn').on('click', () => {
  372. layui.use('table', function() {
  373. var table = layui.table;
  374. var layer = layui.layer;
  375. layer.open({
  376. type: 1,
  377. title: '运行记录',
  378. content: $('#demo'),
  379. offset: ['180px', '45px'],
  380. end: function() {
  381. $('#demo').hide();
  382. $('.layui-table-view').hide()
  383. },
  384. cancel: function(index, layero) {
  385. $('.layui-layer-content')
  386. .hide()
  387. }
  388. });
  389. var tableReload = table.render({
  390. elem: '#demo',
  391. width: 300,
  392. page: {
  393. elem: '#demo',
  394. layout: ['prev', 'page', 'next',
  395. 'count'
  396. ]
  397. },
  398. url: 'http://192.168.0.40:8081/reportTable/getAutoChReportTable',
  399. where: {
  400. autoTableId: id
  401. },
  402. text: {
  403. none: '暂无数据' //默认:无数据。
  404. },
  405. cols: [
  406. [{
  407. field: 'reportTableName',
  408. title: null,
  409. width: 300
  410. }]
  411. ],
  412. parseData: function(res) {
  413. return {
  414. "code": 0,
  415. "msg": res.msg,
  416. "count": res.data.count,
  417. "data": res.data
  418. .reportTableList
  419. };
  420. }
  421. });
  422. //触发行单击事件
  423. table.on('row(test)', function(obj) {
  424. const id = obj.data.id
  425. const title = obj.data
  426. .reportTableName
  427. uni.navigateTo({
  428. url: `/pages/reportForm/report-detail/recordDetail?id=${id}&title=${title}`
  429. })
  430. });
  431. $('th').hide()
  432. });
  433. })
  434. });
  435. });
  436. })
  437. </script>
  438. </body>
  439. </html>