英文:
Go adding a extra line in API response when reading from a csv file
问题
当通过我的前端(React)上传文件时,Go语言会读取CSV文件,然后以结构化的格式将数据发送到JSON响应中。
JSON响应:
{
"Success": true,
"labels": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"data": [
{
"label": "",
"data": null,
"borderColor": "",
"backgroundColor": ""
},
{
"label": "Kyle",
"data": [
"1517",
"1689",
"1719",
"1591",
"1490",
"1310",
"1533",
"1500",
"1400",
"1300",
"1600",
"1800"
],
"borderColor": "#f6ff00",
"backgroundColor": "#f6ff00"
},
{
"label": "Mickey",
"data": [
"3000",
"3100",
"3200",
"3000",
"3500",
"4000",
"3700",
"3500",
"3000",
"4000",
"5000",
"4000"
],
"borderColor": "#ff0000",
"backgroundColor": "#ff0000"
},
{
"label": "Donald",
"data": [
"2500",
"2000",
"2800",
"3000",
"3100",
"2900",
"2800",
"3000",
"3200",
"3400",
"3500",
"3800"
],
"borderColor": "#001eff",
"backgroundColor": "#001eff"
}
]
}
你可以看到问题出在data字段下的这一行:
{"label":"","data":null,"borderColor":"","backgroundColor":""}
我不知道为什么Go会添加这一行。
CSV文件:
,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
Kyle,1517,1689,1719,1591,1490,1310,1533,1500,1400,1300,1600,1800
Mickey,3000,3100,3200,3000,3500,4000,3700,3500,3000,4000,5000,4000
Donald,2500,2000,2800,3000,3100,2900,2800,3000,3200,3400,3500,3800
func RouteUpload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
r.ParseMultipartForm(16 * 1024 * 1024) // 16MB
file, handler, err := r.FormFile("file")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
defer file.Close()
// 在文件系统上创建一个空文件
f, err := os.OpenFile(filepath.Join("uploads", handler.Filename), os.O_WRONLY|os.O_CREATE, 0666)
defer f.Close()
// 将文件复制到images目录中
io.Copy(f, file)
w.Header().Set("Content-Type", "application/json")
type MyData struct {
Label string `json:"label"`
Data []string `json:"data"`
BorderColor string `json:"borderColor"`
BackgroundColor string `json:"backgroundColor"`
}
type MyFile struct {
Success bool `json:"Success"`
Labels []string `json:"labels"`
Data []MyData `json:"data"`
}
var myData MyData
var myFile MyFile
path := "uploads/" + handler.Filename
// 打开文件
fi, err := os.Open(path)
if err != nil {
log.Fatal(err)
}
// 程序结束时记得关闭文件
defer f.Close()
// 使用csv.Reader读取csv值
csvReader := csv.NewReader(fi)
data, err := csvReader.ReadAll()
if err != nil {
fmt.Println(err)
}
colors := []string{"#00ff12", "#f6ff00", "#ff0000", "#001eff", "#ea00ff", "#ff9600"}
for i, line := range data {
if i == 0 {
for j, field := range line {
if j == 0 {
} else {
myFile.Labels = append(myFile.Labels, field)
}
}
} else {
fmt.Println(line)
for j, field := range line {
if j == 0 {
myData.Label = field
} else {
myData.Data = append(myData.Data, field)
}
}
myData.BorderColor = colors[i]
myData.BackgroundColor = colors[i]
}
myFile.Data = append(myFile.Data, myData)
myData.Data = []string{}
}
myFile.Success = true
// 转换为JSON格式
responseJson, err := json.Marshal(myFile)
if err != nil {
fmt.Println(err)
}
// 以JSON格式发送成功响应给用户
fmt.Fprintf(w, "%s\n", responseJson)
}
英文:
When uploading a file through my frontend (React), Go is reading the csv file and then sending the data in a structured format in a JSON response.
The JSON response:
{
"Success": true,
"labels": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"data": [
{
"label": "",
"data": null,
"borderColor": "",
"backgroundColor": ""
},
{
"label": "Kyle",
"data": [
"1517",
"1689",
"1719",
"1591",
"1490",
"1310",
"1533",
"1500",
"1400",
"1300",
"1600",
"1800"
],
"borderColor": "#f6ff00",
"backgroundColor": "#f6ff00"
},
{
"label": "Mickey",
"data": [
"3000",
"3100",
"3200",
"3000",
"3500",
"4000",
"3700",
"3500",
"3000",
"4000",
"5000",
"4000"
],
"borderColor": "#ff0000",
"backgroundColor": "#ff0000"
},
{
"label": "Donald",
"data": [
"2500",
"2000",
"2800",
"3000",
"3100",
"2900",
"2800",
"3000",
"3200",
"3400",
"3500",
"3800"
],
"borderColor": "#001eff",
"backgroundColor": "#001eff"
}
]
}
You see the problem is this line under data:
{"label":"","data":null,"borderColor":"","backgroundColor":""}
I do not know why this is being added in by Go
The CSV file:
,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
Kyle,1517,1689,1719,1591,1490,1310,1533,1500,1400,1300,1600,1800
Mickey,3000,3100,3200,3000,3500,4000,3700,3500,3000,4000,5000,4000
Donald,2500,2000,2800,3000,3100,2900,2800,3000,3200,3400,3500,3800
func RouteUpload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
r.ParseMultipartForm(16 * 1024 * 1024) // 16MB
file, handler, err := r.FormFile("file")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
defer file.Close()
// Create an empty file on filesystem
f, err := os.OpenFile(filepath.Join("uploads", handler.Filename), os.O_WRONLY|os.O_CREATE, 0666)
defer f.Close()
// Copy the file to the images directory
io.Copy(f, file)
w.Header().Set("Content-Type", "application/json")
type MyData struct {
Label string `json:"label"`
Data []string `json:"data"`
BorderColor string `json:"borderColor"`
BackgroundColor string `json:"backgroundColor"`
}
type MyFile struct {
Success bool `json:"Success"`
Labels []string `json:"labels"`
Data []MyData `json:"data"`
}
var myData MyData
var myFile MyFile
path := "uploads/" + handler.Filename
// open file
fi, err := os.Open(path)
if err != nil {
log.Fatal(err)
}
// remember to close the file at the end of the program
defer f.Close()
// read csv values using csv.Reader
csvReader := csv.NewReader(fi)
data, err := csvReader.ReadAll()
if err != nil {
fmt.Println(err)
}
colors := []string{"#00ff12", "#f6ff00", "#ff0000", "#001eff", "#ea00ff", "#ff9600"}
for i, line := range data {
if i == 0 {
for j, field := range line {
if j == 0 {
} else {
myFile.Labels = append(myFile.Labels, field)
}
}
} else {
fmt.Println(line)
for j, field := range line {
if j == 0 {
myData.Label = field
} else {
myData.Data = append(myData.Data, field)
}
}
myData.BorderColor = colors[i]
myData.BackgroundColor = colors[i]
}
myFile.Data = append(myFile.Data, myData)
myData.Data = []string{}
}
myFile.Success = true
// Marshal into JSON
responseJson, err := json.Marshal(myFile)
if err != nil {
fmt.Println(err)
}
// Send success response to user in JSON
fmt.Fprintf(w, "%s\n", responseJson)
}
答案1
得分: 1
你正在对CSV文件的第一行进行不同处理,因为有if i==0 {...} else {...}
,但之后你总是将数据追加到myFile.Data
中 - 所以对于i==0,空的myData
也会被追加。尝试将这个追加操作移到else
块中。
还有一些建议:在Go语言中,实际上不鼓励使用if ... else
(参见https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88)。所以对于if i==0
,你可以在for
循环后使用continue
来避免使用else
- 然后你可以将代码移到else
块外部。另外,if j==0 {/*do nothing*/} else {/*do something*/}
应该改为if j!=0 {/*do something*/}
。
英文:
You are treating the first line from the CSV file differently than the others because of the if i==0 {...} else {...}
, but after that you are always appending to myFile.Data
- so for i==0, the empty myData
will be appended. Try moving this append into the else
block.
Some other suggestions: if ... else
is actually discouraged in Go (see https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88). So for the if i==0
, you could avoid the else
by using continue
after the for
loop - then you could move the code out of the else
block. Also, the if j==0 {/*do nothing*/} else {/*do something*/}
should of course be if j!=0 {/*do something*/}
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论