从我的服务器下载*.csv文件

3

我是一个Golang新手,现在正在编写一个小应用程序来解析一些页面。 我得到了索引页面:

<form action="/" method='POST'>
    Enter credentials:<br>
    Login: <input type="text" name="login" >
    <br>
    Password: <input type="password" name="password" >
    <br>
    Search link:<br>
    <input type="text" name="link" >
    <br>
    <input type="submit" value="Submit">
 </form> 

点击“提交”按钮后,代码将跳转到解析页面(使用tebeca/selenium软件包),最终将数据写入result.csv文件。
func writeToCSV(users []linkedinUser) {
data := users
enc := struct2csv.New()
rows, err := enc.Marshal(data)
if err != nil {
    fmt.Printf("ERROR marshaling file, %s", err)
}
file, err := os.Create("result.csv")
if err != nil {
    fmt.Printf("ERROR creating file, %s", err)
}
defer file.Close()

writer := csv.NewWriter(file)
defer writer.Flush()

for _, value := range rows {
    err := writer.Write(value)
    if err != nil {
        fmt.Printf("ERROR writing file, %s", err)
    }
}

最终,我在路径/home/username/go/src/parser/parsertool/src/result.csv中得到了result.csv文件。
我的main.go文件:
func main() {
    r := mux.NewRouter()

    r.HandleFunc("/", indexHandler)
    http.Handle("/", r)

    err := http.ListenAndServe(":3000", nil) // setting listening port
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }


    func indexHandler(w http.ResponseWriter, r *http.Request) {
    t, _ := template.ParseFiles("./front/index.html")
    badLoginT, _ := template.ParseFiles("./front/error.html")
    r.ParseForm()
    login := r.PostFormValue("login")
    password := r.PostFormValue("password")
    link := r.PostFormValue("link")
    if login != "" || password != "" {
        userCred := logincredentials.SetCredentials(login, password)
        if logincredentials.CheckCredentials(userCred) && link != "" {
            crawler.Crawl(link, login, password)
        } else {
            badLoginT.Execute(w, nil)
        }
    }

    t.Execute(w, nil)
}

所以主要问题是: 有没有办法获取一个下载链接,将result.csv文件下载到我的硬盘上? 具体实现不重要。也许在writeToCSV()结束时,会弹出一个窗口,你可以选择保存文件的位置,或者在获取了result.csv文件后,会出现像“点击下载”的链接,单击后您可以看到下载窗口等。

我陷入困境,真的不知道该如何实现下载。 对于任何帮助,我都将感激不尽。

2个回答

5
在您的Go服务器上
func main() {
  r := mux.NewRouter()
  r.HandleFunc("/", indexHandler)
  http.Handle("/", r)
  err := http.ListenAndServe(":3000", nil) // setting listening port
  if err != nil {
    log.Fatal("ListenAndServe: ", err)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    ...
    Openfile, err := os.Open(Filename)
    FileSize := strconv.FormatInt(FileStat.Size(), 10)
    FileContentType := http.DetectContentType(FileHeader)
    //Send the headers before sending the file
    writer.Header().Set("Content-Disposition", "attachment; filename="+Filename)
    writer.Header().Set("Content-Type", FileContentType)
    writer.Header().Set("Content-Length", FileSize)

    //Send the file
   io.Copy(w, Openfile) 
  }

在你的客户端

由于要下载的文件将由服务器发送,因此需要使用js函数首先将表单提交到服务器。然后在收到服务器的响应后,同一函数将直接触发下载。

HTML

<form>
    Enter credentials:<br>
    Login: <input id="login" type="text" name="login" >
    <br>
    Password: <input id="password" type="password" name="password" >
    <br>
    Search link:<br>
    <input id="link" type="text" name="link" >
    <br>
    <input type="button" onclick="downloadFile()">
 </form> 

在一个js文件中
function downloadFile() {
      var data = { 
       login: document.querySelector('#login').value,
       password: document.querySelector('#password').value,
       link: document.querySelector('#link').value
       }

      xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        var a;
        if (xhttp.readyState === 4 && xhttp.status === 200) {
            a = document.createElement('a');
            a.href = window.URL.createObjectURL(xhttp.response);
            // Give to file the name you wish 
            a.download = "test-file.xls";
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
        }
    }
    }

    xhttp.open("POST", urlserver);
    xhttp.setRequestHeader("Content-Type", "application/json");
    // set responseType as blob for binary responses
    xhttp.responseType = 'blob';
    xhttp.send(JSON.stringify(data));

1
Golang使文件服务变得容易。您可以在net/http中使用FileServer组件(如下所示)。您只需要确保将文件保存在您正在提供服务的文件夹中(在下面的示例中为“/static”)。因此,您的代码应该使用专用路径: file, err := os.Create("/home/username/static/result.csv") 并且添加以下FileServer处理程序后,您的文件将在http://domain/static/result.csv下可用。
package main

import (
    "net/http"
)

func main() {
...
    fs := http.FileServer(http.Dir("/home/username/static"))
    http.Handle("/static/", http.StripPrefix("/static", fs))
    http.ListenAndServe(":3000", nil)
...
}

请注意,static文件夹中的所有文件都将被提供服务。欲了解更多信息,请参阅文档
如果您需要帮助编写客户端文件下载,请参考此stackoverflow问题

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接