好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用Vue+Spring Boot实现Excel上传功能

1.使用vue-cli创建前端项目

运用vue-cli工具可以很轻松地构建前端项目,当然,使用webstorm来构建会更加简洁(如图)。本文推荐使用webstorm,因为在后续开发中,ide会使我们的开发更加简洁。部分配置如图:

   

 

2.navbar编写

作为一个webapp,navbar作为应用的导航栏是必不可少的。在本项目中,笔者引入了bootstrap对navbar进行了轻松地构建。在vue中我们需要在components文件夹中将我们的组件加进去,对于本工程来说,navbar是我们要加入的第一个组件,他独立于router之外,一直固定在网页上方。

2.1 首先,我们使用npm来安装vue,vue-cli,bootstrap

?

1

2

3

npm install vue

npm install -g vue-cli

npm install --save bootstrap jquery popper.js

2.2 接下来我们在components目录下new一个vue组件,并且在main.js中引入bootstrap依赖:

?

1

2

import 'bootstrap/dist/css/bootstrap.min.css'

import 'bootstrap/dist/js/bootstrap.min'

2.3 下面就可以开始写代码了,由于本文只关注table相关的功能,所以导航栏中除了script意外的元素都已经disable,代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

<template>

  <nav class = "navbar navbar-expand-lg navbar-dark bg-dark" >

  <span class = "navbar-brand mb-0 h1" >vue-springboot</span>

  <button class = "navbar-toggler" type= "button" data-toggle= "collapse" data-target= "#navbarnav" aria-controls= "navbarnav" aria-expanded= "false" aria-label= "toggle navigation" >

  <span class = "navbar-toggler-icon" ></span>

  </button>

  <div class = "collapse navbar-collapse" id= "navbarnav" >

  <ul class = "navbar-nav" >

  <li class = "nav-item" >

   <router-link class = "nav-link" to= "/home" >home</router-link>

  </li>

  <li class = "nav-item active" >

   <router-link to= "/" class = "nav-link" >script</router-link>

  </li>

  <li class = "nav-item" >

   <router-link to= "/history" class = "nav-link" >history</router-link>

  </li>

  </ul>

  </div>

  </nav>

</template>

<script>

  export default {

  name: "mynavbar"

  }

</script>

<style scoped>

</style>

2.3 在app.vue中引入mynavbar

3.script table编写

作为自动化工具,必不可少的一部分就是引入script,我们希望用户能够自由地使用h5界面进行script的编写,因此在这里使用了vue的数据双向绑定进行table crud。

3.1 新建一个vue组件scripttable,代码如下:

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

<template>

  <div class = "container-fluid" id= "scripttable" >

  <h3>my script</h3>

  <form style= "margin-top: 1rem" >

  <input type= "file" @change = "getfile($event)" class = "" multiple/>

  <input type= "button" value= "upload" @click = "submit($event)" class = "btn btn-dark" >

  </form>

  <table class = "table table-hover text-center table-bordered"

   style= "word-break: break-all; word-wrap: break-word;margin-top: 1rem;" >

  <thead>

  <th>#</th>

  <th>platform</th>

  <th>action</th>

  <th>path</th>

  <th>value</th>

  <th>wait</th>

  <th>screenshot</th>

  <th>change</th>

  </thead>

  <tbody>

  <tr v-cloak v- for = "(item, index) in steps" >

  <th>{{index+ 1 }}</th>

  <td>{{item.platform}}</td>

  <td>{{item.action}}</td>

  <td>{{item.path}}</td>

  <td>{{item.value}}</td>

  <td>{{item.wait}}</td>

  <td>{{item.screenshot}}</td>

  <td><a href= "#" v-on:click= "edit(item)" >edit</a> | <a href= "#" v-on:click= 'aaa(index)' >delete</a>

  </td>

  </tr>

  <tr>

  <th></th>

  <td><select class = "form-control" v-model= "stepstemp.platform" >

   <option>web</option>

   <option>android</option>

  </select></td>

  <td><select class = "form-control" v-model= "stepstemp.action" >

   <option>click</option>

   <option>get</option>

   <option>input</option>

   <option>swipe</option>

  </select></td>

  <td><input class = "form-control" v-model= "stepstemp.path" placeholder= "enter the xpath" ></td>

  <td><input class = "form-control" v-model= "stepstemp.value" placeholder= "enter the input value" ></td>

  <td><input class = "form-control" v-model= "stepstemp.wait" placeholder= "waiting seconds" ></td>

  <td><select class = "form-control" v-model= "stepstemp.screenshot" >

   <option>yes</option>

   <option>no</option>

  </select></td>

  <td>

   <button class = "btn btn-sm btn-dark" v-on:click= 'save' v- if = "isnotedit" >save</button>

   <button class = "btn btn-sm btn-primary" v-on:click= 'saveedit' v- else >saveedit</button>

  </td>

  </tr>

  </tbody>

  </table>

  <hr/>

  </div>

</template>

<script>

  import vue from 'vue'

  import axios from 'axios'

  export default {

  name: "scripttable" ,

  data() {

  return ({

  steps: [],

  stepstemp: {

   platform: '' ,

   action: '' ,

   path: '' ,

   value: '' ,

   wait: '' ,

   screenshot: ''

  },

  isnotedit: true

  });

  },

  methods: {

  save: function () {

  this .steps.push( this .stepstemp);

  this .stepstemp = {

   platform: '' ,

   action: '' ,

   path: '' ,

   value: '' ,

   wait: '' ,

   screenshot: ''

  };

  },

  aaa: function (index) {

  this .steps.splice(index, 1 )

  },

  edit: function (item) {

  this .isnotedit = false ;

  this .stepstemp = item;

  },

  saveedit: function () {

  this .isnotedit = true ;

  this .stepstemp = {

   platform: '' ,

   action: '' ,

   path: '' ,

   value: '' ,

   wait: '' ,

   screenshot: ''

  };

  }

  }

  }

</script>

<style scoped>

</style>

3.3 运行dev,打开localhost:8080

npm run dev

前端页面效果如下:

 

至此,本文相关的纯前端部分完成地差不多了,加上mock的数据后,我们可以开始进行后端的开发了。

4.使用spring initializr创建后端项目

为了更轻松地构建工程,构建restful api以及更轻松地配置请求处理,笔者选择了spring boot作为后端框架。

4.1 首先我们使用idea集成的spring initializr来构建项目,部分配置如图:

 

 

4.2 接下来在pom.xml中引入poi依赖,点击import change。如下所示:

?

1

2

3

4

5

<dependency>

  <groupid>org.apache.poi</groupid>

  <artifactid>poi-ooxml</artifactid>

  <version> 4.0 . 0 </version>

  </dependency>

4.3 接下来我们在application.properties中配置server.port=8088,与前端项目分开

5.pojo类step的编写

下面是对pojo类的编写,本文所需的pojo只有step一种,与前端的table相对应,代码如下:

?

1

2

3

4

5

6

7

8

9

10

import lombok.data;

@data

public class step {

  private string platform;

  private string action;

  private string path;

  private string value;

  private int wait;

  private string screenshot;

}

6.uploadcontroller的编写

接下来是对前端post请求的handler(controller)进行编写,我们将上传这个post请求与"/uploadfile"相对应,注意加入@crossorigin注解实现跨域,代码如下:

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

package com.daniel.vuespringbootuploadbe;

import org.springframework.beans.factory.annotation.autowired;

import org.springframework.stereotype.controller;

import org.springframework.web.bind.annotation.crossorigin;

import org.springframework.web.bind.annotation.postmapping;

import org.springframework.web.bind.annotation.responsebody;

import org.springframework.web.multipart.multipartfile;

import java.io.file;

import java.io.ioexception;

import java.nio.file.files;

import java.nio.file.path;

import java.nio.file.paths;

import java.util.list;

@controller

@crossorigin

@responsebody

public class uploadcontroller {

  private static string uploaded_folder = "src/main/resources/static/temp/" ;

  @autowired

  private loadservice loadservice;

  @postmapping ( "/upload" )

  public list<step> singlefileupload(multipartfile file) {

  try {

   // get the file and save it somewhere

   byte [] bytes = file.getbytes();

   path path = paths.get(uploaded_folder + file.getoriginalfilename());

   files.write(path, bytes);

  } catch (ioexception e) {

   e.printstacktrace();

  }

  // print file data to html

  list<step> result = loadservice.casttostep( new file(uploaded_folder + file.getoriginalfilename()));

  return result;

  }

}

7.loadservice的编写

下面该编写service来读取请求中传送的文件了,简单地来说只有一个步骤,将excel中的script转换为pojo的链表并在controller中作为responsebody返回.

7.1 首先创建service接口,代码如下:

?

1

2

3

4

5

6

7

8

package com.daniel.vuespringbootuploadbe;

import org.springframework.stereotype.service;

import java.io.file;

import java.util.list;

@service

public interface loadservice {

  list<step> casttostep(file file);

}

7.2 接下来创建service实现类,代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

package com.daniel.vuespringbootuploadbe;

import org.apache.poi.openxml4j.exceptions.invalidformatexception;

import org.apache.poi.ss.usermodel.row;

import org.apache.poi.ss.usermodel.sheet;

import org.apache.poi.ss.usermodel.workbook;

import org.apache.poi.xssf.usermodel.xssfworkbook;

import org.springframework.stereotype.service;

import java.io.file;

import java.io.ioexception;

import java.util.arraylist;

import java.util.list;

@service

public class loadserviceimpl implements loadservice {

  @override

  public list<step> casttostep(file file) {

  list<step> steps = new arraylist<>();

  workbook workbook = null ;

  try {

   workbook = new xssfworkbook(file);

  } catch (ioexception e) {

   e.printstacktrace();

  } catch (invalidformatexception e) {

   e.printstacktrace();

  }

  sheet sheet = workbook.getsheetat( 0 );

  int num = sheet.getlastrownum() - sheet.getfirstrownum();

  //read steps

  for ( int i = 0 ; i < num; i++) {

   row row = sheet.getrow(i+ 1 );

   step step = new step();

   step.setplatform(row.getcell( 0 ).getstringcellvalue());

   step.setaction(row.getcell( 1 ).getstringcellvalue());

   step.setpath(row.getcell( 2 ).getstringcellvalue());

   step.setvalue(row.getcell( 3 ).getstringcellvalue());

   step.setwait(( int ) row.getcell( 4 ).getnumericcellvalue());

   step.setscreenshot(row.getcell( 5 ).getstringcellvalue());

   steps.add(step);

  }

  try {

   workbook.close();

  } catch (ioexception e) {

   e.printstacktrace();

  }

  return steps;

  }

}

8.搭建简单的restful api

文章临近尾声,现在前后端的独立代码基本开发完毕,是时候搭建restful了,本文中的api非常简单,就是对上传做出响应,并将返回的json写入界面上的table中,完成script导入,npm安装axios后,在scripttable组件中加入如下代码:

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

getfile: function (event) {

  this .file = event.target.files[ 0 ];

  console.log( this .file);

  },

  submit: function (event) {

  event.preventdefault();

  let formdata = new formdata();

  formdata.append( "file" , this .file);

  axios.post( 'http://localhost:8088/upload' , formdata)

   .then(function (response) {

   for (let i = 0 ; i < response.data.length; i++) {

   var tempdata = {

   platform: response.data[i].platform,

   action: response.data[i].action,

   path: response.data[i].path,

   value: response.data[i].value,

   wait: response.data[i].wait,

   screenshot: response.data[i].screenshot

   };

   this .steps.push(tempdata);

   }

   }.bind( this ))

   . catch (function (error) {

   alert( "fail" );

   console.log(error);

   });

  }

9.运行服务,编写script并上传

接下来我们创建一个excel,按如图格式编写简单script,运行前后端服务,实现上传:

运行后,excel文件会上传到后端工程的static的temp目录中

总结

以上所述是小编给大家介绍的使用vue+spring boot实现excel上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

原文链接:https://juejin.im/post/5bff4a1851882516eb5625a1

查看更多关于使用Vue+Spring Boot实现Excel上传功能的详细内容...

  阅读:26次