1. <template>
  2. <div>
  3. <div id="example-container" class="wrapper">
  4. <HotTable ref="testHot" :root="root" :settings="hotSettings"/>
  5. <el-button type="primary" size="small" @click="saveData">{{ '保存' }}</el-button>
  6. <el-button size="small" @click="goBack">{{ '返回' }}</el-button>
  7. <!--<el-button size="small" @click="goBack">{{ $t('task.next_step') }}</el-button>-->
  8. </div>
  9. </div>
  10. </template>
  11. <script>
  12. import HotTable from 'vue-handsontable-official'
  13. export default {
  14. name: 'SampleApp',
  15. components: {
  16. HotTable
  17. },
  18. props: {
  19. taskid: {
  20. type: String,
  21. default: ''
  22. },
  23. createTaskType: {
  24. type: Boolean,
  25. default: false
  26. },
  27. createTaskForm: {
  28. type: String,
  29. default: ''
  30. }
  31. },
  32. data: function() {
  33. return {
  34. root: 'test-hot',
  35. hotSettings: {
  36. data: [],
  37. // startRows: 11, //行列范围
  38. // startCols: 11,
  39. minRows: 1, // 最小行列
  40. // minCols: 6,
  41. width: '100%',
  42. // maxRows: 30, //最大行列
  43. // maxCols: 30,
  44. rowHeaders: true, // 行表头
  45. height: 320,
  46. rowHeights: 23,
  47. colHeaders: true, // 行表头
  48. // colHeaders: ["时间", "Kia", "Nissan", "Toyota", "Honda", "123"], //自定义列表头or 布尔值
  49. // minSpareCols: 2, //列留白
  50. // minSpareRows: 2, //行留白
  51. currentRowClassName: 'currentRow', // 为选中行添加类名,可以更改样式
  52. currentColClassName: 'currentCol', // 为选中列添加类名
  53. autoWrapRow: true, // 自动换行
  54. contextMenu: {
  55. // 自定义右键菜单,可汉化,默认布尔值
  56. items: {
  57. row_above: {
  58. name: '上方插入一行'
  59. },
  60. row_below: {
  61. name: '下方插入一行'
  62. },
  63. // col_left: {
  64. // name: "左方插入列"
  65. // },
  66. // col_right: {
  67. // name: "右方插入列"
  68. // },
  69. hsep1: '---------', // 提供分隔线
  70. remove_row: {
  71. name: '删除行'
  72. }
  73. // remove_col: {
  74. // name: "删除列"
  75. // },
  76. // make_read_only: {
  77. // name: "只读"
  78. // },
  79. // borders: {
  80. // name: "表格线"
  81. // },
  82. // commentsAddEdit: {
  83. // name: "添加备注"
  84. // },
  85. // commentsRemove: {
  86. // name: "取消备注"
  87. // },
  88. // freeze_column: {
  89. // name: "固定列"
  90. // },
  91. // unfreeze_column: {
  92. // name: "取消列固定"
  93. // },
  94. // hsep2: "---------"
  95. }
  96. }, // 右键效果
  97. fillHandle: true, // 选中拖拽复制 possible values: true, false, "horizontal", "vertical"
  98. fixedColumnsLeft: 0, // 固定左边列数
  99. fixedRowsTop: 0, // 固定上边列数
  100. columns: [
  101. // 添加每一列的数据类型和一些配置
  102. {},
  103. {},
  104. {},
  105. {},
  106. {},
  107. {},
  108. {},
  109. {},
  110. {},
  111. {},
  112. {},
  113. // {},
  114. // {},
  115. // {},
  116. // {},
  117. {},
  118. {},
  119. {},
  120. {},
  121. {},
  122. {},
  123. {},
  124. {}
  125. ],
  126. manualColumnFreeze: true, // 手动固定列
  127. manualColumnMove: true, // 手动移动列
  128. manualRowMove: true, // 手动移动行
  129. manualColumnResize: true, // 手工更改列距
  130. manualRowResize: true, // 手动更改行距
  131. comments: true, // 添加注释
  132. customBorders: [], // 添加边框
  133. columnSorting: true, // 排序
  134. stretchH: 'none' // 根据宽度横向扩展,last:只扩展最后一列,none:默认不扩展
  135. }
  136. }
  137. },
  138.  
  139. mounted() {
  140. // 获取任务详情
  141. console.log(this.taskid)
  142. if (this.taskid) {
  143. this.$store.dispatch('GET_Field_LIST', this.taskid).then(data => {
  144. // 拼column
  145. var columnSize = data.data.columnLargestSize
  146. if (columnSize === 0) {
  147. columnSize = 30
  148. }
  149. var size = []
  150. for (var i = 0; i < columnSize; i++) {
  151. var col = {}
  152. size.push(col)
  153. }
  154. console.log(size)
  155. // this.hotSettings.columns = size;
  156. // 放数据
  157. this.hotSettings.data = data.data.result
  158. })
  159. }
  160. },
  161. methods: {
  162. goBack() {
  163. this.$parent.goback()
  164. // this.$router.push('/integration/task')
  165. },
  166. submit() {
  167. this.postData()
  168. },
  169. transformTf(str) {
  170. return str.replace(/([A-Z])/g, '_$1').toLowerCase()
  171. },
  172. transformStr3(str) {
  173. const re = /_(\w)/g
  174. return str.replace(re, function($0, $1) {
  175. return $1.toUpperCase()
  176. })
  177. },
  178. saveData() {
  179. var examData = this.$refs.testHot.table.getData() // 这里要注意,如果使用this.hotSettings.data 保存表格数据,拖拽完以后数据的顺序将不会更新,因此使用 this.$refs.testHot.table.getData(); 来获取数据,获取的数据格式为二维数组。
  180. var param = []
  181. param.push(examData)
  182. param.push(this.taskid)
  183. this.$store.dispatch('SAVE_Field_LIST', param).then(data => {
  184. this.$notify({
  185. title: '操作成功',
  186. dangerouslyUseHTMLString: true,
  187. type: 'success'
  188. })
  189. console.log(data)
  190. this.goBack()
  191. })
  192. }
  193. }
  194. }
  195. </script>
  196.  
  197. <style>
  198. button {
  199. margin: 20px 20px;
  200. }
  201. .handsontable .currentRow {
  202. background-color: #e7e8ef;
  203. }
  204.  
  205. .handsontable .currentCol {
  206. background-color: #f9f9fb;
  207. }
  208. #test-hot {
  209. width: 800px;
  210. height: 800px;
  211. overflow: hidden;
  212. }
  213. </style>

效果

后端代码 一个用来回显 一个是修改数据

Resource方法

  1. @SuppressWarnings("unchecked")
  2. @RequestMapping(value = "/template/table/{id}", method = {
  3. RequestMethod.GET }, produces = "application/json;charset=UTF-8")
  4. @ResponseBody
  5. @ApiOperation("给在线模版编辑准备的数据")
  6. public ResponseEntity<RestResponse<List<ImportField>>> getTemplateTableField(
  7. @ApiParam(required = true, name = "Authorization", value = "jwt凭证") @RequestHeader(value = "Authorization", required = true) String Authorization,
  8. @PathVariable(value = "id", required = true) String id) throws URISyntaxException, WebException, Exception {
  9. TableTemplateField result = importFieldService.getTableFieldByTemplateId(id);
  10. return ResponseEntity.ok().body(RestResponse.getRestResponse(CommonCodeMessageEnum.SUCCESS.getBizCode(),
  11. CommonCodeMessageEnum.SUCCESS.getMessage(), result));
  12. }
  13.  
  14. @SuppressWarnings("unchecked")
  15. @RequestMapping(value = "/template/table/{id}", method = {
  16. RequestMethod.POST }, produces = "application/json;charset=UTF-8")
  17. @ResponseBody
  18. @ApiOperation("编辑在线模版")
  19. public ResponseEntity<RestResponse<List<ImportField>>> editTemplateTableField(
  20. @ApiParam(required = true, name = "Authorization", value = "jwt凭证") @RequestHeader(value = "Authorization", required = true) String Authorization,@RequestBody List<String[]> json,
  21. @PathVariable(value = "id", required = true) String id){
  22. System.out.println(json.toString());
  23. importFieldService.editTemplateTableField(json,id);
  24. return ResponseEntity.ok().body(RestResponse.getRestResponse(CommonCodeMessageEnum.SUCCESS.getBizCode(),
  25. CommonCodeMessageEnum.SUCCESS.getMessage(), "success"));
  26. }

数据格式,类似一个list<<string>>的格式,返回和接收都是这个格式

  1. [
  2. ["20080101", 10, 11, 12, 13, true],
  3. ["20090101", 20, 11, 14, 13, true],
  4. ["20010101", 30, 15, 12, 13, true],
  5. ["20010101", 32, 213, 21, 312, true],
  6. ["20010201", 32, 213, 21, 312, true],
  7. ["20010301", 32, 213, 21, 312, true],
  8. ["20010401", 32, 213, 21, 312, true],
  9. ["20010501", 32, 213, 21, 312, true],
  10. ["20010601", 32, 213, 21, 312, true]
  11. ],

service方法

  1. /**
  2. * 获取模版字段,转成table
  3. *
  4. * @param id
  5. * @return
  6. */
  7. public TableTemplateField getTableFieldByTemplateId(String id) {
  8. List<List<String>> datalist = new ArrayList<>();
  9. List<ImportField> list = importFieldRepository.findFieldByTemplateId(id);
  10. // 根据rowNumber 分类column
  11. Map<Integer, List<ImportField>> map = list.stream().sorted(Comparator.comparing(ImportField::getColumnNo))
  12. .collect(Collectors.groupingBy(ImportField::getRowNo,
  13. Collectors.mapping(java.util.function.Function.identity(), Collectors.toList())));
  14. for (Integer i : map.keySet()) {
  15. List<String> contentlist = new ArrayList<>();
  16. for (ImportField field : map.get(i)) {
  17. contentlist.add(field.getName() + "(" + field.getLabel() + ")");
  18. }
  19. datalist.add(contentlist);
  20. }
  21. System.out.println(datalist.toString());
  22. TableTemplateField tableTemplateField = new TableTemplateField();
  23. tableTemplateField.setResult(datalist);
  24. // 获取最大的column
  25. Optional<ImportField> importField = list.stream().max(Comparator.comparingInt(ImportField::getColumnNo));
  26. Integer columSize = importField.isPresent() ? importField.get().getColumnNo() : 0;
  27. tableTemplateField.setColumnLargestSize(columSize);
  28. return tableTemplateField;
  29. }
  30.  
  31. /**
  32. * 修改模版field 全删全增
  33. *
  34. * @param json
  35. * @param id
  36. */
  37. public void editTemplateTableField(List<String[]> dataList, String id) {
  38. ImportTemplate template = importTemplateRepository.findOne(id);
  39. Set<ImportField> fields = new HashSet<ImportField>();
  40. if (dataList.size() > 0) {
  41. for (int i = 1; i <= dataList.size(); i++) {
  42. String[] heads = dataList.get(i - 1);
  43. for (int b = 1; b <= heads.length; b++) {
  44. ImportField field = new ImportField();
  45. String fieldcontent = heads[b - 1];
  46. field.setRowNo(i);
  47. field.setColumnNo(b);
  48. // 可能存在空字段
  49. if (!StringUtils.isEmpty(fieldcontent)) {
  50. if (fieldcontent.contains("rowkey")) {
  51. field.setIsRowKey(1);
  52. }
  53. int a = fieldcontent.indexOf("(");
  54. int c = fieldcontent.indexOf(")");
  55. if (a == -1 || c == -1) {
  56. throw new WebException(ErrorEnum.ERR_FIELDNAME_UNFORMATTER);
  57. }
  58. String label = fieldcontent.substring(a + 1, c);
  59. String name = fieldcontent.substring(0, a);
  60. field.setName(name);
  61. field.setLabel(label);
  62. fields.add(field);
  63. }
  64. }
  65. }
  66. if (dataList.size() > 1) {
  67. template.setIsMutipartTitle(1);
  68. }
  69. template.setTitleLine(dataList.size());
  70. template.setImportField(fields);
  71. importTemplateRepository.save(template);
  72. }
  73. }

handsonetable+vue 表格在线编辑的更多相关文章

  1. vue 表格数据编辑,点击取消或者完成按钮后,关闭编辑状态没有及时生效

    点击编辑按钮: 编辑状态下,表格可以编辑.但是点击“确认”或者“取消”按钮,列数据编辑状态已经修改,但是视图没有改变. 页面代码: 获取当前行的index,并直接修改当前行用于判断是否编辑状态的数据为 ...

  2. [前端插件]Bootstrap Table服务器分页与在线编辑应用总结

    先看Bootstrap Table应用效果: 表格用来显示数据库中的数据,数据通过AJAX从服务器加载,同时分页功能有服务器实现,避免客户端分页,在加载大量数据时造成的用户体验不好.还可以设置查询数据 ...

  3. 如何配置使用HTML在线编辑工具

    如何配置使用HTML在线编辑工具 为了更好的.统一的编写统一简单易用的博客,决定采用TinyMCE工具.首先下载TinyMCE4.0包.文件目录如下: 其中, Plugins是插件目录,包括各种插件 ...

  4. ElementUI表格行编辑单元格编辑支持(输入框,选择框)Demo

    嗯,需要做成这个样子,所以网上查了些资料.整理了下.提供几个一个思路.不足之处请小伙伴指出来.  普通版的table可编辑内嵌select选择框,输出框,编辑删除添加等 <!DOCTYPE ht ...

  5. [个人开源]vue-code-view:一个在线编辑、实时预览的代码交互组件

    组件简介 vue-code-view是一个基于 vue 2.x.轻量级的代码交互组件,在网页中实时编辑运行代码.预览效果的代码交互组件. 使用此组件, 不论 vue 页面还是 Markdown 文档中 ...

  6. 在线编辑Word——插入图表

    在Word中可插入图表,配合使用表格能够更加全方位的展示数据的可信度并增加数据的可读性.本文将通过使用在线编辑器 Spire.Cloud Word 演示如何来插入图表,并设置相关格式化操作.具体步骤如 ...

  7. Microsoft Azure Web Sites应用与实践【3】—— 通过Visual Studio Online在线编辑Microsoft Azure 网站

    Microsoft Azure Web Sites应用与实践 系列: [1]—— 打造你的第一个Microsoft Azure Website [2]—— 通过本地IIS 远程管理Microsoft ...

  8. 小讲堂:在线编辑在Mobox文档管理软件中的意义

    今天我们来讨论一下,mobox文档管理软件中的在线编辑的这个功能,相信这个功能是用户在日常的文档维护中非常需要的. 文档管理软件的诸多功能中,在线编辑是一块很重要的功能点,因为在线编辑可以说是提高工作 ...

  9. FineUI大版本升级,外置ExtJS库、去AXD化、表格合计行、表格可编辑单元格的增删改、顶部菜单框架

    这是一篇很长的文章,在开始正文之前,请允许我代表目前排名前 20 中唯一的 .Net 开源软件 FineUI 拉下选票: 投票地址: https://code.csdn.net/2013OSSurve ...

随机推荐

  1. 一文简单理解package-lock.json

    根据官方文档,https://docs.npmjs.com/files/package-lock.json 这个package-lock.json 是在 `npm install`时候生成一份文件,用 ...

  2. JavaScript concat() 方法

    昨天接触了一个项目,我的tbody变量是一个数组,然后数据返回的是数组里面包含对象,我刚开始没看懂这个concat的作用,然后百度一下javascript中的用法,以此记录concat的方法: dat ...

  3. 优化 JS 条件语句及JS 数组常用方法, ---- 看完绝对对日后开发有用

    前言: 日常所说的优化优化.最后我们到底优化了哪些,不如让我们从代码质量开始:个人觉得简洁简化代码其实觉得存在感挺强烈的QAQ 1. 获取URL中 ?后的携带参数: 这是我见过最简洁的了,若有更简洁的 ...

  4. java.util.Arrays (JDK 1.7)

    1.asList //返回由指定数组支持的固定大小的列表,返回的列表是可序列化的 public static <T> List<T> asList(T... a) { retu ...

  5. Big Data(七)MapReduce计算框架(PPT截图)

    一.为什么叫MapReduce? Map是以一条记录为单位映射 Reduce是分组计算

  6. 网页图片失效自动替换图片地址js代码

    当你网页中的图片失效之后它会显示你预先设定好的默认图片,而不是显示为一个大大的红叉叉. js脚本如下: <script language="javascript"> v ...

  7. HTTP/1.1-HTTP/2.0-HTTP/3.0-HTTPS

    HTTP/1.1 网上关于HTTP/1.1的讨论多是基于RFC2616文档,而IETF已更新了HTTP/1.1并将其分为六个部分,使协议变得更简单易懂,对老版本RFC2616中模糊不清的部分做了解释 ...

  8. DP+滚动数组 || [Usaco2007 Nov]Telephone Wire 架设电话线 || BZOJ 1705 || Luogu P2885

    本来是懒得写题解的…想想还是要勤发题解和学习笔记…然后就滚过来写题解了. 题面:[USACO07NOV]电话线Telephone Wire 题解: F[ i ][ j ] 表示前 i 根电线杆,第 i ...

  9. Linux(Centos7)下redis5缓存服务集群分布式搭建

    注意:可以查看Redis官网查看集群搭建方式,连接如下 https://redis.io/topics/cluster-tutorial 集群中应该至少有三个节点,每个节点有一备份节点.需要6台服务器 ...

  10. python中字符串格式化的两种方法

    知识点汇总;1-字符串格式化输出方法一: % 1-print('名字是 %s,年龄是%s' % (name ,age)) 2- %s ---字符串-----相当于执行了str() 3- (name , ...