需求:用户可以上传一个任意的excel表格,根据每一个sheet去将数据导入mysql,首先根据sheetname去判断数据表是否存在,若存在则用sheetname+编号创建表,若不存在则直接用sheetname创建表,创建完表后,将数据导入该表中。(excel的列和类型也是不固定)
package main
import (
"database/sql"
"fmt"
"strconv"
"strings"
_ "github.com/go-sql-driver/mysql"
"github.com/tealeg/xlsx"
)
func main() {
// 解析Excel文件
file := "/path/to/file.xlsx"
xlsxFile, err := xlsx.OpenFile(file)
if err != nil {
panic(err)
}
// 连接数据库
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/db_name")
// 遍历所有Sheet
for _, sheet := range xlsxFile.Sheets {
// 获取Sheet名作为表名
name := sheet.Name
// 检查数据库是否存在该表
var count int
db.QueryRow("SELECT count(*) as count FROM information_schema.tables WHERE table_schema = 'db_name' AND table_name = ?", name).Scan(&count)
// 如果存在,使用name_n作为表名
if count > 0 {
name = fmt.Sprintf("%s_%d", name, count)
}
// 获取字段定义
fields := getFields(sheet)
// 创建表
stmt := fmt.Sprintf("CREATE TABLE %s (%s)", name, strings.Join(fields, ","))
db.Exec(stmt)
// 插入数据
insertData(db, name, sheet)
}
}
// 获取字段定义
func getFields(sheet *xlsx.Sheet) []string {
var fields []string
for _, row := range sheet.Rows {
for _, cell := range row.Cells {
// 获取值类型
switch cell.Type() {
case xlsx.CellTypeString:
fields = append(fields, fmt.Sprintf("`%s` VARCHAR(255)", cell.String()))
case xlsx.CellTypeInt:
fields = append(fields, fmt.Sprintf("`%s` INT", cell.String()))
case xlsx.CellTypeFloat:
fields = append(fields, fmt.Sprintf("`%s` FLOAT", cell.String()))
case xlsx.CellTypeDate:
fields = append(fields, fmt.Sprintf("`%s` DATE", cell.String()))
case xlsx.CellTypeBool:
fields = append(fields, fmt.Sprintf("`%s` TINYINT(1)", cell.String()))
}
}
break
}
return fields
}
// 插入数据
func insertData(db *sql.DB, name string, sheet *xlsx.Sheet) {
// 获取列名
var colNames []string
for _, cell := range sheet.Rows[0].Cells {
colNames = append(colNames, cell.String())
}
// 遍历行数据
for idx, row := range sheet.Rows {
if idx == 0 {
continue
}
// 拼接值
var colValues []string
for _, cell := range row.Cells {
switch cell.Type() {
case xlsx.CellTypeString:
colValues = append(colValues, "'" + cell.String() + "'")
case xlsx.CellTypeInt:
colValues = append(colValues, strconv.Itoa(cell.Num()))
case xlsx.CellTypeFloat:
colValues = append(colValues, strconv.FormatFloat(cell.Num(), 'f', -1, 64))
case xlsx.CellTypeBool:
colValues = append(colValues, strconv.FormatBool(cell.Bool()))
case xlsx.CellTypeDate:
colValues = append(colValues, cell.Date().Format("2006-01-02"))
}
}
// 拼接SQL并执行
stmt := fmt.Sprintf(
"INSERT INTO %s (%s) VALUES (%s)",
name,
strings.Join(colNames, ","),
strings.Join(colValues, ","),
)
db.Exec(stmt)
}
}