Spring Boot入門(8)文件上傳和數據預覽

介紹

  本次分享將具體介紹如何在Spring Boot中實現文件上傳和數據預覽。
  咱們將實現CSV文件的數據預覽和部分圖片格式的查看。主要的思路以下:javascript

  • 利用Spring Boot的MultipartFile實現文件的上傳;
  • 利用Spring MVC實現整個文件上傳流程的控制;
  • 利用javacsv API實現CSV文件的讀取;
  • 利用JavaScript實現CSV文件的數據預覽

  話很少說,咱們直接上項目!css

項目介紹

  整個項目的結構以下:html

整個項目的結構

  主要是兩部分的內容,一部分是Controller(控制器),一部分是view(視圖)文件。UploadController.java是控制器,其代碼以下:java

package com.hello.upload.Controller;

import java.util.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
public class UploadController{

    private String filename;
    //Save the uploaded file to this folder
    private static String UPLOADED_FOLDER = "E://upload/src/main/resources/static/images/";

    /*
    **文件上傳頁面
     */

    @GetMapping("/upload")
    public String upload(){
        return "upload";
    }

    @PostMapping("/upload")
    public String singleFileUpload(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {

        if (file.isEmpty()) {
            redirectAttributes.addFlashAttribute("message", "文件爲空! 請選擇非空文件上傳!");
            return "redirect:/uploadStatus";
        }

        try {
            // 獲取文件並保存到指定文件夾中
            byte[] bytes = file.getBytes();
            filename = file.getOriginalFilename();
            Path path = Paths.get(UPLOADED_FOLDER + filename);
            Files.write(path, bytes);

            redirectAttributes.addFlashAttribute("message", "您已成功上傳 '" + filename + "', 該文件大小約爲 " +bytes.length/1024+" KB.");

        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return "redirect:/uploadStatus";
    }

    /*
    ** 文件上傳信息處理頁面
     */
    @GetMapping("/uploadStatus")
    public String uploadStatus(){
        return "uploadStatus";
    }

    /*
    ** 數據預覽頁面: 支持CSV文件和部分圖片格式的預覽
     */

    @GetMapping("/review")
    public String review(Map<String, Object> map) {

        map.put("filename", filename);
        String filetype = filename.split("\\.")[1];
        map.put("filetype",filetype);
        System.out.println(filename);

        if(filetype.equals("csv")) {
            readCSV read_csv = new readCSV(UPLOADED_FOLDER + filename);
            List<String> result = read_csv.read();
            map.put("result", result);
        }

        return "review";
    }

}

  文件上傳的錯誤處理包含在代碼GlobalExceptionHandler.java中,其代碼以下:jquery

package com.hello.upload.Controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MultipartException.class)
    public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {

        redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
        return "redirect:/uploadStatus";

    }

}

  接着readCSV.java主要實現CSV文件內容的讀取,其代碼以下:git

package com.hello.upload.Controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.csvreader.CsvReader;

/*
** readCSV類:實現CSV文件內容的讀取
 */
public class readCSV {

    // 參數:文件路徑
    private String file_path;

    // 構造函數
    readCSV(){}

    readCSV(String file_path){
        this.file_path = file_path;
    }

    // getter and setter
    public String getFile_path() {
        return file_path;
    }

    public void setFile_path(String file_path) {
        this.file_path = file_path;
    }

    // read()函數實現具體的讀取CSV文件內容的方法
    public List<String> read() {

        List<String> result = new ArrayList<>();

        try {
            // 建立CSV讀對象
            CsvReader csvReader = new CsvReader(file_path);
            while (csvReader.readRecord()){
                // 讀取每一行數據,以逗號分開
                // System.out.println(csvReader.getRawRecord());
                result.add(csvReader.getRawRecord());
            }
            csvReader.close();
            return result;

        } catch (IOException e) {
            e.printStackTrace();
            return result;
        }
    }

}

  接着是視圖部分,文件都位於templates文件夾下。upload.html文件主要是文件上傳的頁面,其代碼以下:github

<!DOCTYPE HTML>

<html xmlns:th="http://www.thymeleaf.org">

<head>
    <title>Upload files by Spring Boot</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<body>

<center>
    <br><br><br>
    <div class="panel panel-primary" style="width:600px">
        <div class="panel-heading">
            <h3 class="panel-title">文件上傳</h3>
        </div>
        <div class="panel-body">
            <form class="form-horizontal" role="form" method="POST" action="/upload" enctype="multipart/form-data">

                <div class="form-group" style="width:600px">
                    <label for="upload" class="col-sm-2 control-label">選擇文件</label>
                    <div class="col-sm-10">
                        <input type="file" id="upload" name="file" />
                    </div>
                </div>


                <div class="form-group">
                    <div>
                        <button type="submit" class="btn btn-success" id="btn_upload">提交</button>
                        <input type="reset" class="btn btn-danger" value="重置" />

                    </div>
                </div>

            </form>
        </div>
    </div>

</center>

</body>

</html>

  uploadStatus.html文件主要用來展現文件上傳的信息,包括上傳成功和失敗的信息,其代碼以下:web

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>

<center>
    <br><br>
    <h2>文件上傳狀態</h2>

    <br><br>
    <div class="panel panel-success" style="width:1000px">

        <div class="panel-heading">
            <h3 class="panel-title">文件上傳</h3>
        </div>

        <div class="panel-body">

            <div th:if="${message}">
                <h3 th:text="${message}"/>
            </div>

        </div>

    </div>

    <a href="/upload"><button class="btn btn-primary">返回文件上傳</button></a>
    <a href="/review"><button class="btn btn-warning" id="review">數據預覽</button></a>
    </center>

</body>

</html>

  接着是數據預覽部分的HTML,主要實現CSV文件的預覽和部分圖片格式的查看,其代碼以下:spring

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>文件預覽</title>
    <link href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <link href="/css/table.css" rel="stylesheet">

    <script th:inline="javascript">
    var filetype = [[${filetype}]];
    var filename = [[${filename}]];

    function show(){
        if(filetype == "csv"){
            showTable();
        }
        else if((filetype=="jpg") || (filetype=="png") || (filetype=="gif") || (filetype=="bmp")){
            document.getElementById("content").innerHTML = filename;
            document.getElementById("image").src = "/images/"+filename ;
        }
        else{
            document.getElementById("content").innerHTML = "文件預覽只支持csv文件以及部分格式的圖片文件!"
        }
    }

    function showTable(){

    document.getElementById("content").innerHTML = filename;
    var thread_content = document.getElementById("index").innerHTML+"";
    if (thread_content == ""){
        var result = /*[[${result}]]*/ null ;
        var col_count = result[0].split(",").length;
        if(result.length > 51){
            var record_count = 51;
        }
        else{
            var record_count = result.length;
        }
        // 展現表格各個變量的名稱
        var headers = result[0].split(",");
        row=document.createElement("tr"); //建立行
        for(var i=0; i< col_count; i++){
            th1=document.createElement("th"); //建立單元格
            th1.appendChild(document.createTextNode(headers[i])); //爲單元格添加內容
            row.appendChild(th1); //將單元格添加到行內
        }
        document.getElementById("index").append(row); //將行添加到<thread>中
        for(var i=1; i < record_count; i++){
            row=document.createElement("tr"); //建立行
            for(var j=0; j< col_count; j++){
                td1=document.createElement("td"); //建立單元格
                td1.appendChild(document.createTextNode(result[i].split(",")[j])); //爲單元格添加內容
                row.appendChild(td1); //將單元格添加到行內
            }
            document.getElementById("body").append(row); //將行添加到<thread>中
        }
        }

    }
</script>
</head>

<body>

<br><br>
<center>

    <button class="btn btn-danger" onclick="show()">文件預覽</button>
    <a href="/upload"><button class="btn btn-warning" id="review">返回主界面</button></a>
    <br><br>

    <p id="content"></p>

    <div style="width:800px">
        <table class="table table-striped table-condensed table-responsive">
            <thead id="index"></thead>
            <tbody id="body"></tbody>
        </table>
    </div>

    <img id="image" src="" />

</center>

</body>

</html>

  最後將如下咱們的配置文件,application.properties代碼以下:bootstrap

server.port=8100

spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=5MB
spring.http.multipart.enabled=false

其設置網絡端口爲8100,每次上傳的文件大小不超過5MB.項目構建文件build.gradle的代碼以下:

buildscript {
    ext {
        springBootVersion = '2.0.1.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile group: 'net.sourceforge.javacsv', name: 'javacsv', version: '2.0'
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

運行及測試

  好不容易寫完了項目,不測試一把,對不起觀衆啊。
  啓動Spring Boot項目,在瀏覽器中輸入:http://localhost:8100/upload,頁面以下:

上傳文件頁面

  選擇本地的mpg.csv文件上傳,它將會上傳至E://upload/src/main/resources/static/images/ 文件夾中,上傳成功後的頁面以下圖:

文件上傳成功

  點擊數據預覽按鈕,跳轉到review.html頁面,再點擊該頁面的數據預覽按鈕,顯示的頁面以下圖:

CSV文件預覽

  固然也支持部分圖片格式的預覽,例如:movie.jpg,以下圖:

圖片預覽

  當上傳文件大於5MB時,顯示的信息以下:

錯誤信息展現

  本次分享到此結束,該項目的Github地址爲: https://github.com/percent4/U... 。 接下來還會繼續更新Spring Boot方面的內容,歡迎你們交流~~

相關文章
相關標籤/搜索