提问人:carlcaroline 提问时间:11/3/2023 最后编辑:Zach Youngcarlcaroline 更新时间:11/5/2023 访问量:62
从 csv 文件中提取数据并将其放入 golang 中给出的模板中
pull data from csv file and put it into template given in golang
问:
有人知道如何根据其列从上传为 multipart.file 的 CSV 文件中提取数据,然后将数据输入到另一个 CSV 文件(模板)?
我仍然无法获得在 golang 中执行此操作的正确逻辑。这是CSV文件的样子:
"Coorporate",,,
Address :,,,
Boulevard Street,,,
Service / Office : 021-62318113 / 021-22684901,,,
"VGA WITH GUARANTEE",Dealer,Msrp,MARGIN
VGA-1,"37,000","38,000","1,000"
VGA-2,"27,500","28,500","1,000"
CASE ,Dealer ,Msrp ,MARGIN
CASE-1 ,"430,000","480,000","50,000"
CASE-2 ,"450,000","500,000","50,000"
"MAXSUN VGA ",Dealer ,Msrp ,MARGIN
MVGA-1,"13,300,000","13,800,000","500,000"
这些是我尝试读取以检测表头(至少具有“Msrp”列的行)的代码:
reader := csv.NewReader(f)
records, err := reader.ReadAll()
var rows []string
columns := []string{"Msrp", "MSRP", "msrp"}
for _, column := range columns {
for _, columnName := range records {
for _, cols := range columnName {
if cols == column {
row := strings.Join(columnName, " ")
rows = append(rows, row)
break
}
}
}
但它只返回表头。我需要获取每列的值并将其保存到新的切片中(也许?),以便以后可以使用刚刚从上传的CSV文件中提取的值更新CSV模板文件
假设我有一个结构:
type columnName struct {
PartName string json:"part_name"
Price int json:"price"
Msrp int json:"msrp"
}
如何将列名与该结构匹配?
有没有更好的方法来解决这个问题?
无论如何,我是golang的新手,编程请帮助我
非常感谢!
答:
0赞
poone
11/3/2023
#1
看起来 的返回可能会有一些混淆。
表示整个表。
如果遍历 ,则可以逐行打印。reader := csv.NewReader(f)
reader
reader
像这样,写一个测试并打印出数据,你就会有一个清晰的认识。
reader := csv.NewReader(file)
//the first line data is the titles
titles, _ = reader.Read()
// perform a data comparison with columns := []string{"Msrp", "MSRP", "msrp"}
// allocate a container below to store it
//loop the row
for {
records, _ = reader.Read() // the records
// the records is a var record []string
// you should loop that value
//there record[1], record[2], record[3] is your col
}
希望这能帮到你
评论
0赞
carlcaroline
11/3/2023
哦,谢谢你纠正我。无论如何,您知道我应该如何处理它,以便假设我有一个结构类型 columnName struct { PartName string SourceName string Price int Msrp int Ppn bool } 我如何将列名与该结构相匹配json:"part_name"
json:"source_name"
json:"price"
json:"msrp"
json:"ppn"
1赞
poone
11/3/2023
如果要在运行时动态检索 struct 字段,则应使用包 。获取使用 .或者,您可以定义一个映射进行映射,这可能是一种更简单的尝试方法。reflect
relect.TypeOf and the name through typ.Field
0赞
Zach Young
11/4/2023
#2
我清理了您共享的输入 CSV:
Coorporate,,,
Address :,,,
Boulevard Street,,,
Service / Office : 021-62318113 / 021-22684901,,,
VGA WITH GUARANTEE,Dealer,Msrp,MARGIN
VGA-1,"37,000","38,000","1,000"
VGA-2,"27,500","28,500","1,000"
CASE,Dealer,Msrp,MARGIN
CASE-1,"430,000","480,000","50,000"
CASE-2,"450,000","500,000","50,000"
MAXSUN VGA,Dealer,Msrp,MARGIN
MVGA-1,"13,300,000","13,800,000","500,000"
在对齐的表视图中查看它:
| Coorporate | | | |
| Address : | | | |
| Boulevard Street | | | |
| Service / Office : 021-62318113 / 021-22684901 | | | |
| VGA WITH GUARANTEE | Dealer | Msrp | MARGIN |
| VGA-1 | 37,000 | 38,000 | 1,000 |
| VGA-2 | 27,500 | 28,500 | 1,000 |
| CASE | Dealer | Msrp | MARGIN |
| CASE-1 | 430,000 | 480,000 | 50,000 |
| CASE-2 | 450,000 | 500,000 | 50,000 |
| MAXSUN VGA | Dealer | Msrp | MARGIN |
| MVGA-1 | 13,300,000 | 13,800,000 | 500,000 |
看起来顶部有几行不会出现在最终数据中,所以我遍历它们并忽略它们:
f, _ := os.Open("input.csv")
r := csv.NewReader(f)
// iterate and discard Coorporate ... Service / Office...
for i := 0; i < 4; i++ {
_, err := r.Read()
if doneReading(err) {
break
}
}
我把我的结构做成这样的:
type Record struct {
PartName string `json:"part_name"`
Price int `json:"price"`
Msrp int `json:"msrp"`
}
现在,我可以迭代其余的行,并警惕中间的标题,如果我看到一个标题,我只需继续下一行即可将其删除,这应该是真实的数据。对于真实的数据行,格式看起来很简单——所以我可以直接将第 2 列和第 3 列解析为 ints(检查错误),将结果附加到我的 Records 切片中,然后将其全部转换为 JSON:string, string, int, int
Records := make([]Record, 0)
for i := 5; ; i++ {
record, err := r.Read()
if doneReading(err) {
break
}
col3 := strings.TrimSpace(record[2])
// discard records that look like an intermediate header
// with "MSRP" in the 3rd colum
if strings.ToLower(col3) == "msrp" {
continue
}
col1 := strings.TrimSpace(record[0])
col2 := strings.TrimSpace(record[1])
price, err1 := strconv.Atoi(strings.ReplaceAll(col2, ",", ""))
msrp, err2 := strconv.Atoi(strings.ReplaceAll(col3, ",", ""))
if err1 != nil || err2 != nil {
log.Printf("could not parse ints in Col2 and/or Col3 of row %d: %v\n", i, record)
}
Records = append(Records, Record{col1, price, msrp})
}
b, err := json.MarshalIndent(Records, "", " ")
must(err)
fmt.Println(string(b))
我看到:
[
{
"part_name": "VGA-1",
"price": 37000,
"msrp": 38000
},
{
"part_name": "VGA-2",
"price": 27500,
"msrp": 28500
},
{
"part_name": "CASE-1",
"price": 430000,
"msrp": 480000
},
{
"part_name": "CASE-2",
"price": 450000,
"msrp": 500000
},
{
"part_name": "MVGA-1",
"price": 13300000,
"msrp": 13800000
}
]
其中一个数字列中的错误数据会被记录下来,如下所示:
2009/11/10 23:00:00 could not parse ints in Col2 and/or Col3 of row 6: [VGA-1 37,000 38,000--AAA 1,000]
下面是一个完整的示例,Go Playground。
评论