经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
使用Vue+Spring Boot实现Excel上传功能
来源:jb51  时间:2018/11/30 9:15:17  对本文有异议

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. npm install vue
  2. npm install -g vue-cli
  3. npm install --save bootstrap jquery popper.js

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

  1. import 'bootstrap/dist/css/bootstrap.min.css'
  2. import 'bootstrap/dist/js/bootstrap.min'

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

  1. <template>
  2. <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  3. <span class="navbar-brand mb-0 h1">Vue-SpringBoot</span>
  4. <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
  5. <span class="navbar-toggler-icon"></span>
  6. </button>
  7. <div class="collapse navbar-collapse" id="navbarNav">
  8. <ul class="navbar-nav">
  9. <li class="nav-item">
  10. <router-link class="nav-link" to="/home">Home</router-link>
  11. </li>
  12. <li class="nav-item active">
  13. <router-link to="/" class="nav-link">Script</router-link>
  14. </li>
  15. <li class="nav-item">
  16. <router-link to="/history" class="nav-link">History</router-link>
  17. </li>
  18. </ul>
  19. </div>
  20. </nav>
  21. </template>
  22. <script>
  23. export default {
  24. name: "MyNavbar"
  25. }
  26. </script>
  27. <style scoped>
  28. </style>

2.3 在App.vue中引入MyNavbar

3.Script Table编写

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

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

  1. <template>
  2. <div class="container-fluid" id="scriptTable">
  3. <h3>My Script</h3>
  4. <form style="margin-top: 1rem">
  5. <input type="file" @change="getFile($event)" class="" multiple/>
  6. <input type="button" value="upload" @click="submit($event)" class="btn btn-dark">
  7. </form>
  8. <table class="table table-hover text-center table-bordered"
  9. style="word-break: break-all; word-wrap: break-word;margin-top: 1rem;">
  10. <thead>
  11. <th>#</th>
  12. <th>Platform</th>
  13. <th>Action</th>
  14. <th>Path</th>
  15. <th>Value</th>
  16. <th>Wait</th>
  17. <th>Screenshot</th>
  18. <th>Change</th>
  19. </thead>
  20. <tbody>
  21. <tr v-cloak v-for="(item, index) in steps">
  22. <th>{{index+1}}</th>
  23. <td>{{item.platform}}</td>
  24. <td>{{item.action}}</td>
  25. <td>{{item.path}}</td>
  26. <td>{{item.value}}</td>
  27. <td>{{item.wait}}</td>
  28. <td>{{item.screenshot}}</td>
  29. <td><a href="#" v-on:click="edit(item)">Edit</a> | <a href="#" v-on:click='aaa(index)'>Delete</a>
  30. </td>
  31. </tr>
  32. <tr>
  33. <th></th>
  34. <td><select class="form-control" v-model="stepstemp.platform">
  35. <option>Web</option>
  36. <option>Android</option>
  37. </select></td>
  38. <td><select class="form-control" v-model="stepstemp.action">
  39. <option>click</option>
  40. <option>get</option>
  41. <option>input</option>
  42. <option>swipe</option>
  43. </select></td>
  44. <td><input class="form-control" v-model="stepstemp.path" placeholder="Enter the xPath"></td>
  45. <td><input class="form-control" v-model="stepstemp.value" placeholder="Enter the input value"></td>
  46. <td><input class="form-control" v-model="stepstemp.wait" placeholder="Waiting seconds"></td>
  47. <td><select class="form-control" v-model="stepstemp.screenshot">
  48. <option>yes</option>
  49. <option>no</option>
  50. </select></td>
  51. <td>
  52. <button class="btn btn-sm btn-dark" v-on:click='save' v-if="isNotEdit">Save</button>
  53. <button class="btn btn-sm btn-primary" v-on:click='saveEdit' v-else>SaveEdit</button>
  54. </td>
  55. </tr>
  56. </tbody>
  57. </table>
  58. <hr/>
  59. </div>
  60. </template>
  61. <script>
  62. import Vue from 'vue'
  63. import axios from 'axios'
  64. export default {
  65. name: "ScriptTable",
  66. data() {
  67. return ({
  68. steps: [],
  69. stepstemp: {
  70. platform: '',
  71. action: '',
  72. path: '',
  73. value: '',
  74. wait: '',
  75. screenshot: ''
  76. },
  77. isNotEdit: true
  78. });
  79. },
  80. methods: {
  81. save: function () {
  82. this.steps.push(this.stepstemp);
  83. this.stepstemp = {
  84. platform: '',
  85. action: '',
  86. path: '',
  87. value: '',
  88. wait: '',
  89. screenshot: ''
  90. };
  91. },
  92. aaa: function (index) {
  93. this.steps.splice(index, 1)
  94. },
  95. edit: function (item) {
  96. this.isNotEdit = false;
  97. this.stepstemp = item;
  98. },
  99. saveEdit: function () {
  100. this.isNotEdit = true;
  101. this.stepstemp = {
  102. platform: '',
  103. action: '',
  104. path: '',
  105. value: '',
  106. wait: '',
  107. screenshot: ''
  108. };
  109. }
  110. }
  111. }
  112. </script>
  113. <style scoped>
  114. </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. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi-ooxml</artifactId>
  4. <version>4.0.0</version>
  5. </dependency>

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

5.pojo类Step的编写

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

  1. import lombok.Data;
  2. @Data
  3. public class Step {
  4. private String platform;
  5. private String action;
  6. private String path;
  7. private String value;
  8. private int wait;
  9. private String screenshot;
  10. }

6.UploadController的编写

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

  1. package com.daniel.vuespringbootuploadbe;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.CrossOrigin;
  5. import org.springframework.web.bind.annotation.PostMapping;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. import org.springframework.web.multipart.MultipartFile;
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.nio.file.Files;
  11. import java.nio.file.Path;
  12. import java.nio.file.Paths;
  13. import java.util.List;
  14. @Controller
  15. @CrossOrigin
  16. @ResponseBody
  17. public class UploadController {
  18. private static String UPLOADED_FOLDER = "src/main/resources/static/temp/";
  19. @Autowired
  20. private LoadService loadService;
  21. @PostMapping("/upload")
  22. public List<Step> singleFileUpload(MultipartFile file) {
  23. try {
  24. // Get the file and save it somewhere
  25. byte[] bytes = file.getBytes();
  26. Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
  27. Files.write(path, bytes);
  28. } catch (IOException e) {
  29. e.printStackTrace();
  30. }
  31. // Print file data to html
  32. List<Step> result = loadService.castToStep(new File(UPLOADED_FOLDER + file.getOriginalFilename()));
  33. return result;
  34. }
  35. }

7.LoadService的编写

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

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

  1. package com.daniel.vuespringbootuploadbe;
  2. import org.springframework.stereotype.Service;
  3. import java.io.File;
  4. import java.util.List;
  5. @Service
  6. public interface LoadService {
  7. List<Step> castToStep(File file);
  8. }

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

  1. package com.daniel.vuespringbootuploadbe;
  2. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  3. import org.apache.poi.ss.usermodel.Row;
  4. import org.apache.poi.ss.usermodel.Sheet;
  5. import org.apache.poi.ss.usermodel.Workbook;
  6. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  7. import org.springframework.stereotype.Service;
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. @Service
  13. public class LoadServiceImpl implements LoadService {
  14. @Override
  15. public List<Step> castToStep(File file) {
  16. List<Step> steps = new ArrayList<>();
  17. Workbook workbook = null;
  18. try {
  19. workbook = new XSSFWorkbook(file);
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. } catch (InvalidFormatException e) {
  23. e.printStackTrace();
  24. }
  25. Sheet sheet = workbook.getSheetAt(0);
  26. int num = sheet.getLastRowNum() - sheet.getFirstRowNum();
  27. //Read steps
  28. for (int i = 0; i < num; i++) {
  29. Row row = sheet.getRow(i+1);
  30. Step step = new Step();
  31. step.setPlatform(row.getCell(0).getStringCellValue());
  32. step.setAction(row.getCell(1).getStringCellValue());
  33. step.setPath(row.getCell(2).getStringCellValue());
  34. step.setValue(row.getCell(3).getStringCellValue());
  35. step.setWait((int) row.getCell(4).getNumericCellValue());
  36. step.setScreenshot(row.getCell(5).getStringCellValue());
  37. steps.add(step);
  38. }
  39. try {
  40. workbook.close();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. return steps;
  45. }
  46. }

8.搭建简单的RESTful API

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

  1. getFile: function (event) {
  2. this.file = event.target.files[0];
  3. console.log(this.file);
  4. },
  5. submit: function (event) {
  6. event.preventDefault();
  7. let formData = new FormData();
  8. formData.append("file", this.file);
  9. axios.post('http://localhost:8088/upload', formData)
  10. .then(function (response) {
  11. for (let i = 0; i < response.data.length; i++) {
  12. var tempData = {
  13. platform: response.data[i].platform,
  14. action: response.data[i].action,
  15. path: response.data[i].path,
  16. value: response.data[i].value,
  17. wait: response.data[i].wait,
  18. screenshot: response.data[i].screenshot
  19. };
  20. this.steps.push(tempData);
  21. }
  22. }.bind(this))
  23. .catch(function (error) {
  24. alert("Fail");
  25. console.log(error);
  26. });
  27. }

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

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

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

总结

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号