使用Go创建Excel报告时出现时间和小时格式问题

时间:2019-10-24 10:21:30

标签: excel go

我正在尝试根据数据库中的特定表格生成Excel工作表。我用于生成Excel的库是excelize

这是表: enter image description here

这是完整的代码:

package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "time"

    "github.com/360EntSecGroup-Skylar/excelize"
    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"

    _ "github.com/lib/pq"
)

const (
    host     = "localhost"
    port     = 2019
    user     = "postgres"
    password = "dbadmin"
    dbname   = "oc-indo-dev"
)

type M map[string]interface{}

func DBconnect() *sql.DB {
    psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
        "password=%s dbname=%s sslmode=disable",
        host, port, user, password, dbname)
    db, err := sql.Open("postgres", psqlInfo)

    if err != nil {
        log.Fatal(err)
    }

    return db
}

/*
type NullString struct {
    sql.NullString
}
*/

type NullTime struct {
    sql.NullString
}

/*
func (ns *NullString) MarshalJSON() ([]byte, error) {
    if !ns.Valid {
        return []byte("null"), nil
    }
    return json.Marshal(ns.String)
}
*/

type NullDate struct {
    sql.NullString
}

func (nd *NullDate) MarshalJSON() ([]byte, error) {
    if !nd.Valid {
        return []byte("null"), nil
    }

    t, err := time.Parse(time.RFC3339, nd.String)

    if err != nil {
        fmt.Println(err)
    }
    return json.Marshal(t.Format("02-01-2006"))
}

func (nt *NullTime) MarshalJSON() ([]byte, error) {
    if !nt.Valid {
        return []byte("null"), nil
    }

    //t, err := time.Parse("3 04 PM", nt.String)
    //t, err := time.Parse(time.RFC3339, "0000-01-01T16:29:02+07:00")
    t, err := time.Parse(time.RFC3339, nt.String)

    if err != nil {
        fmt.Println(err)
    }
    return json.Marshal(t.Format("15:04:05"))
}

type LogItem struct {
    UserId      string   `form:"id" json:"id"`
    UserName    string   `form:"name" json:"name"`
    UserDate    NullDate `form:"date" json:"date"`
    CheckinTime NullTime `form:"checkintime" json:"checkintime"`
    //CheckinLocation  NullString `form:"checkinlocation" json:"checkinlocation"`
    CheckoutTime NullTime `form:"checkouttime" json:"checkouttime"`
    //CheckoutLocation NullString `form:"checkoutlocation" json:"checkoutlocation"`
    CheckinDistance  sql.NullInt64 `form:"checkindistance" json:"checkindistance"`
    CheckoutDistance sql.NullInt64 `form:"checkoutdistance" json:"checkoutdistance"`
}

func main() {

    headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"})
    originsOk := handlers.AllowedOrigins([]string{"*"})
    methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})

    router := mux.NewRouter()
    router.HandleFunc("/report", doCreateReport).Methods("GET")
    http.Handle("/", router)
    fmt.Println("Connected to port 1234...")
    log.Fatal(http.ListenAndServe(":1234", handlers.CORS(originsOk, headersOk, methodsOk)(router)))
}

func doCreateReport(w http.ResponseWriter, r *http.Request) {
    var sqlQuery string
    var arrLogItem []LogItem
    var logItem LogItem

    sqlQuery = "SELECT oc_log.userid, oc_user.username, oc_log.userdate, oc_log.checkin_time, oc_log.checkin_distance, oc_log.checkout_time, oc_log.checkout_distance FROM oc_log join oc_user on oc_user.userid = oc_log.userid;"
    db := DBconnect()
    defer db.Close()

    rows, err := db.Query(sqlQuery)
    if err != nil {
        log.Print(err)
    }

    for rows.Next() {
        if err := rows.Scan(&logItem.UserId, &logItem.UserName, &logItem.UserDate, &logItem.CheckinTime, &logItem.CheckinDistance, &logItem.CheckoutTime, &logItem.CheckoutDistance); err != nil {
            log.Fatal(err.Error())

        } else {
            arrLogItem = append(arrLogItem, logItem)
        }
    }

    xlsx := excelize.NewFile()
    sheet1Name := "Sheet One"
    xlsx.SetSheetName(xlsx.GetSheetName(1), sheet1Name)

    xlsx.SetCellValue(sheet1Name, "A1", "User ID")
    xlsx.SetCellValue(sheet1Name, "B1", "Name")
    xlsx.SetCellValue(sheet1Name, "C1", "Date")
    xlsx.SetCellValue(sheet1Name, "D1", "Checkin hour")
    xlsx.SetCellValue(sheet1Name, "E1", "Checkin distance")
    xlsx.SetCellValue(sheet1Name, "F1", "Checkout hour")
    xlsx.SetCellValue(sheet1Name, "G1", "Checkout distance")

    for idx, elem := range arrLogItem {
        xlsx.SetCellValue(sheet1Name, fmt.Sprintf("A%d", idx+2), elem.UserId)
        xlsx.SetCellValue(sheet1Name, fmt.Sprintf("B%d", idx+2), elem.UserName)
        xlsx.SetCellValue(sheet1Name, fmt.Sprintf("C%d", idx+2), elem.UserDate)
        xlsx.SetCellValue(sheet1Name, fmt.Sprintf("D%d", idx+2), elem.CheckinTime)
        xlsx.SetCellValue(sheet1Name, fmt.Sprintf("E%d", idx+2), elem.CheckinDistance)
        xlsx.SetCellValue(sheet1Name, fmt.Sprintf("F%d", idx+2), elem.CheckoutTime)
        xlsx.SetCellValue(sheet1Name, fmt.Sprintf("G%d", idx+2), elem.CheckoutDistance)
    }

    err = xlsx.SaveAs("./report.xlsx")
    if err != nil {
        fmt.Println(err)
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(arrLogItem)
}

转换为JSON的表格看起来不错:

 {
        "id": "9",
        "name": "Tester 02",
        "date": "07-10-2019",
        "checkintime": "12:41:40",
        "checkouttime": null,
        "checkindistance": {
            "Int64": 0,
            "Valid": true
        },
        "checkoutdistance": {
            "Int64": 0,
            "Valid": false
        }
    },
    {
        "id": "9",
        "name": "Tester 02",
        "date": "08-10-2019",
        "checkintime": "17:59:17",
        "checkouttime": null,
        "checkindistance": {
            "Int64": 0,
            "Valid": true
        },
        "checkoutdistance": {
            "Int64": 0,
            "Valid": false
        }
    },
    {
        "id": "9",
        "name": "Tester 02",
        "date": "11-10-2019",
        "checkintime": "12:17:53",
        "checkouttime": null,
        "checkindistance": {
            "Int64": 0,
            "Valid": true
        },
        "checkoutdistance": {
            "Int64": 0,
            "Valid": false
        }
    },
    {
        "id": "10",
        "name": "Jack",
        "date": "17-10-2019",
        "checkintime": null,
        "checkouttime": "15:01:30",
        "checkindistance": {
            "Int64": 0,
            "Valid": false
        },
        "checkoutdistance": {
            "Int64": 4,
            "Valid": true
        }
    },
    {
        "id": "10",
        "name": "Jack",
        "date": "17-10-2019",
        "checkintime": null,
        "checkouttime": "15:02:05",
        "checkindistance": {
            "Int64": 0,
            "Valid": false
        },
        "checkoutdistance": {
            "Int64": 4,
            "Valid": true
        }
    },
    {
        "id": "10",
        "name": "Jack",
        "date": "17-10-2019",
        "checkintime": "15:03:11",
        "checkouttime": null,
        "checkindistance": {
            "Int64": 4,
            "Valid": true
        },
        "checkoutdistance": {
            "Int64": 0,
            "Valid": false
        }
    },

现在,由代码创建的Excel文件: enter image description here

很显然,存在格式问题。例如,您会在JSON中看到

  

“日期”:“ 25-09-2019”,           “ checkintime”:“ 14:56:39”,           “ checkouttime”:“ 15:52:22”,

但是它在Excel中显示为:

  

{{2019-09-25T00:00:00Z是}} {{0000-01-01T14:56:39 + 07:00是}} {0   true} {{0000-01-01T15:52:22 + 07:00 true}}

然后如何在Excel中正确格式化小时/时间?

0 个答案:

没有答案