index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. <template>
  2. <div class="test2">
  3. <div class="mb-md">
  4. <div v-if="grooveData.xlsxTitleShow" class="demo-input-suffix">
  5. 表格名称:
  6. <el-input v-model="title" placeholder="请输入表格名称" style="width: 400px" />
  7. </div>
  8. <div v-if="grooveData.saveShow" class="demo-input-suffix">
  9. <el-button type="success" @click="save">保存</el-button>
  10. </div>
  11. <div v-if="grooveData.clickHandleShow" class="demo-input-suffix">
  12. <el-button type="warning" @click="clickHandle">上传xlsx</el-button>
  13. </div>
  14. <div class="demo-input-suffix">
  15. <el-button type="info" @click="exportExcelBtn">导出xlsx</el-button>
  16. </div>
  17. <input ref="inputFile" type="file" style="display: none" @change="chageFile">
  18. <!-- <div v-if="!grooveData.xlsxTitleShow && !grooveData.saveShow && !grooveData.clickHandleShow && !grooveData.exportExcelShow" style="height: 30px"></div> -->
  19. </div>
  20. <!--web spreadsheet组件-->
  21. <div class="excel" :style="{height: height + 'px'}">
  22. <div id="luckysheetDom" ref="luckysheet" style="margin: 0px; padding: 0px; width:100%; height: 100%;z-index: 100;" />
  23. <!-- <div id="luckysheetDom" ref="luckysheet" style="margin: 0px; padding: 0px; width: calc(100% + 200px); height: calc(100% + 50px);z-index: 100;" /> -->
  24. </div>
  25. </div>
  26. </template>
  27. <script>
  28. // 引入依赖包
  29. import LuckyExcel from 'luckyexcel'
  30. const luckysheet = window.luckysheet
  31. // 代码见下
  32. import { exportExcel } from './js/export'
  33. import { upload } from '@/api/detection/jtsjpz'
  34. import curdPost from '@/business/platform/form/utils/custom/joinCURD.js'
  35. export default {
  36. name: 'xspreadsheet-demo',
  37. props: {
  38. id: {
  39. type: String,
  40. default: ''
  41. },
  42. dialogShow: {
  43. type: Boolean,
  44. default: false
  45. },
  46. grooveData: {
  47. type: Object,
  48. default: function () {
  49. return {
  50. title: '提示',
  51. saveShow: true,
  52. exportExcelShow: true,
  53. clickHandleShow: true,
  54. xlsxTitleShow: true,
  55. readOnly: true,
  56. showtoolbarConfig: null,
  57. cellRightClickConfig: null,
  58. showstatisticBarConfig: null
  59. }
  60. }
  61. },
  62. grooveList: {
  63. type: Array,
  64. default: () => {
  65. return []
  66. }
  67. }
  68. },
  69. data () {
  70. return {
  71. option: null,
  72. showtoolbarConfig: {
  73. // //自定义配置工具栏
  74. undoRedo: true, // 撤销重做,注意撤消重做是两个按钮,由这一个配置决定显示还是隐藏
  75. paintFormat: true, // 格式刷
  76. currencyFormat: true, // 货币格式
  77. percentageFormat: true, // 百分比格式
  78. numberDecrease: true, // '减少小数位数'
  79. numberIncrease: true, // '增加小数位数
  80. moreFormats: true, // '更多格式'
  81. font: true, // '字体'
  82. fontSize: true, // '字号大小'
  83. bold: true, // '粗体 (Ctrl+B)'
  84. italic: true, // '斜体 (Ctrl+I)'
  85. strikethrough: true, // '删除线 (Alt+Shift+5)'
  86. underline: true, // '下划线 (Alt+Shift+6)'
  87. textColor: true, // '文本颜色'
  88. fillColor: true, // '单元格颜色'
  89. border: true, // '边框'
  90. mergeCell: true, // '合并单元格'
  91. horizontalAlignMode: true, // '水平对齐方式'
  92. verticalAlignMode: true, // '垂直对齐方式'
  93. textWrapMode: true, // '换行方式'
  94. textRotateMode: false, // '文本旋转方式'
  95. image: false, // '插入图片'
  96. link: false, // '插入链接'
  97. chart: false, // '图表'(图标隐藏,但是如果配置了chart插件,右击仍然可以新建图表)
  98. postil: false, // '批注'
  99. pivotTable: false, // '数据透视表'
  100. function: true, // '公式'
  101. frozenMode: false, // '冻结方式'
  102. sortAndFilter: false, // '排序和筛选'
  103. conditionalFormat: false, // '条件格式'
  104. dataVerification: false, // '数据验证'
  105. splitColumn: false, // '分列'
  106. screenshot: true, // '截图'
  107. findAndReplace: true, // '查找替换'
  108. protection: false, // '工作表保护'
  109. print: false // '打印'
  110. },
  111. cellRightClickConfig: {
  112. // 右键单元格菜单设置
  113. copy: true, // 复制
  114. copyAs: true, // 复制为
  115. paste: true, // 粘贴
  116. insertRow: true, // 插入行
  117. insertColumn: true, // 插入列
  118. deleteRow: true, // 删除选中行
  119. deleteColumn: true, // 删除选中列
  120. deleteCell: true, // 删除单元格
  121. hideRow: false, // 隐藏选中行和显示选中行
  122. hideColumn: false, // 隐藏选中列和显示选中列
  123. rowHeight: true, // 行高
  124. columnWidth: true, // 列宽
  125. clear: true, // 清除内容
  126. matrix: false, // 矩阵操作选区
  127. sort: false, // 排序选区
  128. filter: false, // 筛选选区
  129. chart: false, // 图表生成
  130. image: false, // 插入图片
  131. link: false, // 插入链接
  132. data: false, // 数据验证
  133. cellFormat: true // 设置单元格格式
  134. },
  135. showstatisticBarConfig: {
  136. // 自定义配置底部计数栏
  137. count: false, // 计数栏
  138. view: true, // 打印视图
  139. zoom: true // 缩放
  140. },
  141. title: this.grooveData.title,
  142. height: ''
  143. }
  144. },
  145. created () {
  146. if (this.dialogShow) {
  147. this.height = window.innerHeight - 110
  148. } else {
  149. this.height = window.innerHeight - 150
  150. }
  151. if (this.grooveData.showtoolbarConfig && Object.keys(this.grooveData.showtoolbarConfig).length > 0) {
  152. Object.keys(this.grooveData.showtoolbarConfig).forEach(item => {
  153. this.showtoolbarConfig[item] = this.grooveData.showtoolbarConfig[item]
  154. })
  155. }
  156. if (this.grooveData.cellRightClickConfig && Object.keys(this.grooveData.cellRightClickConfig).length > 0) {
  157. Object.keys(this.grooveData.cellRightClickConfig).forEach(item => {
  158. this.cellRightClickConfig[item] = this.grooveData.cellRightClickConfig[item]
  159. })
  160. }
  161. if (this.grooveData.showstatisticBarConfig && Object.keys(this.grooveData.showstatisticBarConfig).length > 0) {
  162. Object.keys(this.grooveData.showstatisticBarConfig).forEach(item => {
  163. this.showstatisticBarConfig[item] = this.grooveData.showstatisticBarConfig[item]
  164. })
  165. }
  166. },
  167. mounted () {
  168. if (this.id) {
  169. this.getInitData(this.id)
  170. // this.init()
  171. } else {
  172. this.init()
  173. }
  174. },
  175. destroyed () {
  176. luckysheet.destroy()
  177. // this.$refs.luckysheet.remove()
  178. },
  179. methods: {
  180. init () {
  181. let options = ''
  182. if (!options) {
  183. options = {
  184. container: 'luckysheetDom',
  185. title: '',
  186. lang: 'zh',
  187. data: [
  188. {
  189. name: 'sheet1'
  190. }
  191. ],
  192. showtoolbarConfig: this.showtoolbarConfig,
  193. showinfobar: false,
  194. cellRightClickConfig: this.cellRightClickConfig,
  195. showstatisticBarConfig: this.showstatisticBarConfig
  196. }
  197. }
  198. if (this.grooveList.length > 0) {
  199. this.grooveList.forEach((item, index) => {
  200. if (!item.name) {
  201. item.name = 'sheet' + index
  202. }
  203. })
  204. options.data = this.grooveList
  205. }
  206. // 可开启只读模式
  207. // options.allowEdit = false
  208. // this.option = options
  209. luckysheet.create(options)
  210. },
  211. // 获取数据表的数据
  212. getInitData (id) {
  213. const sql = `select * from t_pbgl where id_ = '${id}'`
  214. curdPost('sql', sql).then((res) => {
  215. if (res.state === '200') {
  216. const dataItem = res.variables.data[0]
  217. this.title = dataItem.shu_ju_ming_cheng
  218. const options = JSON.parse(dataItem.shu_ju_cun_chu_)
  219. luckysheet.create(options)
  220. }
  221. })
  222. },
  223. save () {
  224. const data = luckysheet.toJson()
  225. if (this.id) {
  226. this.updateSumbit(data)
  227. } else {
  228. this.getSumbit(data)
  229. }
  230. },
  231. // 下载文档
  232. exportExcelBtn () {
  233. console.log(luckysheet.toJson())
  234. const title = this.title ? this.title : '下载'
  235. exportExcel(luckysheet.getluckysheetfile(), title)
  236. },
  237. // 上传文档
  238. clickHandle () {
  239. this.$refs.inputFile.click()
  240. },
  241. chageFile () {
  242. this.importExcel(this.$refs.inputFile.files[0])
  243. },
  244. importExcel (file) {
  245. const name = file.name
  246. this.title = name.split('.xlsx')[0]
  247. // 获取文件后缀
  248. const suffixArr = name.split('.')
  249. const suffix = suffixArr[suffixArr.length - 1]
  250. if (suffix !== 'xlsx') {
  251. alert('目前只能导入xlsx类型的文件')
  252. return
  253. }
  254. LuckyExcel.transformExcelToLucky(file, this.fileCb, this.errorCb)
  255. },
  256. fileCb (exportJson, luckysheetfile) {
  257. // 转换后获取工作表数据
  258. if (exportJson.sheets === null || exportJson.sheets.length === 0) {
  259. alert('无法读取excel文件的内容,当前不支持xls文件!')
  260. return
  261. }
  262. luckysheet.destroy()
  263. luckysheet.create({
  264. container: 'luckysheetDom', // luckysheet is the container id
  265. data: exportJson.sheets,
  266. title: exportJson.info.name,
  267. userInfo: exportJson.info.name.creator,
  268. lang: 'zh',
  269. showtoolbarConfig: this.showtoolbarConfig,
  270. showinfobar: false,
  271. cellRightClickConfig: this.cellRightClickConfig,
  272. showstatisticBarConfig: this.showstatisticBarConfig
  273. })
  274. },
  275. errorCb (error) {},
  276. printFn () {
  277. // 1. 实现全选
  278. $('#luckysheet-left-top').click()
  279. // 2. 生成选区的截图
  280. const src = luckysheet.getScreenshot()
  281. const $img = `<img src=${src} style="max-width: 90%;" />`
  282. this.$nextTick(() => {
  283. document.querySelector('#print_html').innerHTML = $img
  284. })
  285. // 3. 调用系统打印:已经用v-print指令绑定在打印按钮上
  286. },
  287. getSumbit (option) {
  288. if (this.title === '') {
  289. this.$message({
  290. showClose: true,
  291. message: '请填写表格名称',
  292. type: 'warning'
  293. })
  294. return
  295. }
  296. const data = {
  297. shu_ju_cun_chu_: JSON.stringify(option),
  298. shu_ju_lei_xing_: '在线编辑',
  299. shu_ju_ming_cheng: this.title,
  300. bao_cun_dao_chu_s: JSON.stringify(luckysheet.getluckysheetfile())
  301. }
  302. const params = {
  303. tableName: 't_pbgl',
  304. paramWhere: [data]
  305. }
  306. curdPost('add', params).then((res) => {
  307. if (res.state == '200') {
  308. const dataItem = res.variables.cont[0]
  309. this.id = dataItem.id_
  310. this.$emit('addClick', dataItem.id_, dataItem)
  311. this.$message({
  312. showClose: true,
  313. message: this.title + '的文档' + '保存成功',
  314. type: 'success'
  315. })
  316. }
  317. })
  318. },
  319. updateSumbit (option) {
  320. if (this.title === '') {
  321. this.$message({
  322. showClose: true,
  323. message: '请填写表格名称',
  324. type: 'warning'
  325. })
  326. return
  327. }
  328. const data = {
  329. where: {
  330. id_: this.id
  331. },
  332. param: {
  333. shu_ju_cun_chu_: JSON.stringify(option),
  334. shu_ju_lei_xing_: '在线编辑',
  335. shu_ju_ming_cheng: this.title,
  336. bao_cun_dao_chu_s: JSON.stringify(luckysheet.getluckysheetfile())
  337. }
  338. }
  339. const allSampleParams = {
  340. tableName: 't_pbgl',
  341. updList: [data]
  342. }
  343. curdPost('update', allSampleParams).then((res) => {
  344. if (res.state === '200') {
  345. this.$emit('addClick', this.id, option)
  346. this.$message({
  347. showClose: true,
  348. message: this.title + '的文档' + '修改成功',
  349. type: 'success'
  350. })
  351. }
  352. })
  353. }
  354. }
  355. }
  356. </script>
  357. <style scoped lang="less">
  358. .mb-md {
  359. padding: 10px;
  360. display: flex;
  361. }
  362. .demo-input-suffix {
  363. margin-right: 10px;
  364. }
  365. .test2 {
  366. // width: 100%;
  367. // height: 100%;
  368. // display: flex;
  369. // flex-direction: column;
  370. .excel {
  371. flex: 1;
  372. height: 500px;
  373. }
  374. }
  375. </style>