doupike2351
doupike2351
2018-04-30 16:25
浏览 112
已采纳

从我的服务器下载* .csv

I am new to Golang and now I'm writing small app which parse some page. I got index page:

<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> 

So after clicking Submit button it goes to parse page (using tebeca/selenium pkg), and in the end writes data to result.csv like

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)
    }
}

And in the end I got result.csv file in /home/username/go/src/parser/parsertool/src/result.csv

my 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)
}

So the main question: is there a way to get a link to download result.csv to my hard drive? The implementation isn`t important. May be in the end of writeToCSV() when result.csv is ready, window where you could choose where to save file will appear, or after getting result.csv, some link like "Click to download" will appear and after clicking you can see download window etc.

I'm stuck and really don't have any idea how to implement downloading. I would be grateful for any help.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duanlu1876
    duanlu1876 2018-04-30 17:42
    已采纳

    On your Go server

    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) 
      }
    

    In your client

    Since the file to be downloaded will be sent by the server, one need to use a js function to post the form first to the server. Then after receiving the response of the server, the download will be triggered directly by the same function.

    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> 
    

    In a js file

    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));
    
    点赞 评论
  • dongsi5381
    dongsi5381 2018-04-30 17:21

    Golang makes serving files easy. You can use the FileServer component in net/http (see below). You just need to make sure to save the file in the folder that you are serving ("/static" in the example below). So your code should use a dedicated path:

    file, err := os.Create("/home/username/static/result.csv")

    And with the following FileServer handler added, your file would be available under 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)
    ...
    }
    

    Note that all files under static will be served. For more information see the docs.

    If you need help how to write the client side for a file download please refer to this stackoverflow question.

    点赞 评论

相关推荐