Golang中如何解析CSV文件并存储到数组

Golang中如何解析CSV文件并存储到数组 如标题所述,我没有收到任何错误,但在提交CSV文件后它也没有打印任何内容。

fmt.Fprint(w, "Here is options", options)

我正在使用的HTML模板:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Car Project</title>
</head>
<body>
<h1>Please upload your inventory CSV</h1>

<form action="/uploadCSV" method="post">
<input type="file" id="myFile" name="filename">
<input type="submit">
</form>


</body>
</html>

Go代码:

package main

import (
	"encoding/csv"
	"fmt"
	"log"
	"net/http"
	"text/template"
)

var tpl *template.Template
var options []carInvSchema

type carInvSchema struct {
	Id          string
	Make        string
	Model       string
	Description string
	Mileage     string
	Price       string
	Term        string
}

func init() {
	tpl = template.Must(template.ParseGlob("templates/*"))
}

func main() {
	http.HandleFunc("/", index)
	// http.HandleFunc("/uploadCSV", parsedCSV)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, req *http.Request) {

	if req.Method == http.MethodPost {

		//processing form submisson
		//opening file
		file, _, err := req.FormFile("filename")
		if err != nil {
			http.Error(w, "Unable to upload file", http.StatusInternalServerError)
		}
		defer file.Close()

		//reading file
		rdr := csv.NewReader(file)
		rows, err := rdr.ReadAll()
		if err != nil {
			log.Fatalln(err)
		}

		options = make([]carInvSchema, 0, len(rows))
		//ranging over the rows
		for i, row := range rows {
			if i == 0 {
				continue
			}
			id := row[0]
			make := row[1]
			model := row[2]
			description := row[3]
			mileage := row[4]
			price := row[5]
			term := row[6]

			options = append(options, carInvSchema{
				Id:          id,
				Make:        make,
				Model:       model,
				Description: description,
				Mileage:     mileage,
				Price:       price,
				Term:        term,
			})
		}

	}

	err := tpl.ExecuteTemplate(w, "index.gohtml", nil)
	if err != nil {
		log.Fatal("Unable to execute template")
	}
}

// func parsedCSV(w http.ResponseWriter, req *http.Request) {
// 	w.Header().Set("Content-Type", "text/html; charset=utf-8")
// 	err := tpl.ExecuteTemplate(w, "parseddata.gohtml", options)
// 	if err != nil {
// 		log.Fatal("Unable to execute template")
// 	}
// }


更多关于Golang中如何解析CSV文件并存储到数组的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何解析CSV文件并存储到数组的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题在于你的HTML表单没有正确设置enctype="multipart/form-data"属性,导致文件上传失败。此外,你需要在POST请求处理完成后重定向或显示结果。以下是修正后的代码:

HTML模板修正:

<form action="/uploadCSV" method="post" enctype="multipart/form-data">
    <input type="file" id="myFile" name="filename">
    <input type="submit">
</form>

Go代码修正:

package main

import (
    "encoding/csv"
    "fmt"
    "log"
    "net/http"
    "text/template"
)

var tpl *template.Template
var options []carInvSchema

type carInvSchema struct {
    Id          string
    Make        string
    Model       string
    Description string
    Mileage     string
    Price       string
    Term        string
}

func init() {
    tpl = template.Must(template.ParseGlob("templates/*"))
}

func main() {
    http.HandleFunc("/", index)
    http.HandleFunc("/uploadCSV", uploadCSV)
    http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, req *http.Request) {
    err := tpl.ExecuteTemplate(w, "index.gohtml", nil)
    if err != nil {
        log.Fatal("Unable to execute template")
    }
}

func uploadCSV(w http.ResponseWriter, req *http.Request) {
    if req.Method != http.MethodPost {
        http.Redirect(w, req, "/", http.StatusSeeOther)
        return
    }

    file, _, err := req.FormFile("filename")
    if err != nil {
        http.Error(w, "Unable to upload file", http.StatusInternalServerError)
        return
    }
    defer file.Close()

    rdr := csv.NewReader(file)
    rows, err := rdr.ReadAll()
    if err != nil {
        http.Error(w, "Unable to parse CSV", http.StatusInternalServerError)
        return
    }

    options = make([]carInvSchema, 0, len(rows))
    for i, row := range rows {
        if i == 0 {
            continue
        }
        if len(row) < 7 {
            continue
        }
        
        options = append(options, carInvSchema{
            Id:          row[0],
            Make:        row[1],
            Model:       row[2],
            Description: row[3],
            Mileage:     row[4],
            Price:       row[5],
            Term:        row[6],
        })
    }

    // 打印解析结果到响应
    fmt.Fprintf(w, "Parsed %d records:\n", len(options))
    for _, opt := range options {
        fmt.Fprintf(w, "ID: %s, Make: %s, Model: %s, Price: %s\n", 
            opt.Id, opt.Make, opt.Model, opt.Price)
    }
}

如果需要使用模板显示结果:

func uploadCSV(w http.ResponseWriter, req *http.Request) {
    // ... 前面的解析代码相同 ...

    // 使用模板渲染结果
    err = tpl.ExecuteTemplate(w, "parseddata.gohtml", options)
    if err != nil {
        http.Error(w, "Unable to render template", http.StatusInternalServerError)
    }
}

parseddata.gohtml模板示例:

<!DOCTYPE html>
<html>
<head>
    <title>Parsed CSV Data</title>
</head>
<body>
    <h1>Parsed CSV Data</h1>
    <table border="1">
        <tr>
            <th>ID</th>
            <th>Make</th>
            <th>Model</th>
            <th>Description</th>
            <th>Mileage</th>
            <th>Price</th>
            <th>Term</th>
        </tr>
        {{range .}}
        <tr>
            <td>{{.Id}}</td>
            <td>{{.Make}}</td>
            <td>{{.Model}}</td>
            <td>{{.Description}}</td>
            <td>{{.Mileage}}</td>
            <td>{{.Price}}</td>
            <td>{{.Term}}</td>
        </tr>
        {{end}}
    </table>
</body>
</html>

主要修正点:

  1. HTML表单添加enctype="multipart/form-data"
  2. 分离GET和POST请求处理
  3. 添加错误处理和边界检查
  4. 提供两种结果展示方式:直接输出或模板渲染
回到顶部