dongniuxia8650 2015-02-13 17:06
浏览 88
已采纳

如何使用GO(golang)将SQLX结果嵌入HTML

I am trying to embed results from a Sql Query into an html table using GO as the back end. To iterate row results in Go, the Rows.Next() function is used. This works for printing to the console window, but not for a html table. Here is my Go Code:

package main
// Database connection Code for http://play.golang.org/p/njPBsg0JjD

import (
    "net/http"
    "html/template"
    "fmt"
    "github.com/LukeMauldin/lodbc"
    "github.com/jmoiron/sqlx"
    "database/sql"
)

//declare database class
var db *sqlx.DB

type webdata struct {
    Title string
    Heading string
    GridTitle string
    ColumnHeading [9]string
    RowData [9]string
    NumOfRows *sql.Rows
}

//this is the function handler to handle '/mbconsole'
func ConsoleHandler(w http.ResponseWriter, r *http.Request) {

    //declare an instance of webdata
    var wdata webdata

    //connect to database
    //Set ODBC driver level
    lodbc.SetODBCVersion(lodbc.ODBCVersion_3)

    var err error
    //connect to a Microsoft SQL Server
    db, err = sqlx.Open("lodbc", "[connectionstring]")
    if err == nil {
        fmt.Println("Connection successful")
    }else{
        fmt.Println("SQL Connection error", err)
    }

    // Execute the queries
    rows, err := db.Query("[Select ...]")
    if err != nil {
        panic(err.Error())
    }


    // Get column names
    columns, err := rows.Columns()
    if err != nil {
        panic(err.Error())
    }


    // Make a slice for the values
    values := make([]interface{}, len(columns))

    // rows.Scan wants '[]interface{}' as an argument, so we must copy the
    // references into such a slice
    // See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details
    scanArgs := make([]interface{}, len(values))

    for i := range values {
        scanArgs[i] = &values[i]
    }
    //fill table headings, the table returns 9 columns so I just hard coded it
    for i:=0;i<9;i++ {
        wdata.ColumnHeading[i] = columns[i]
    }

    wdata.NumOfRows = rows

    // Fetch rows
    for rows.Next() {
        err = rows.Scan(scanArgs...)
        if err != nil {
            panic(err.Error())
        }
        // Print data
        for i, value := range values {
            switch value.(type) {
            case nil:
                wdata.RowData[i] = "NULL"
            case []byte:
                wdata.RowData[i] = string(value.([]byte))
            default:
                wdata.RowData[i] = fmt.Sprint(value)
            }
        }
    }

    wdata.Title = "Page Title"
    wdata.Heading = "My View"
    wdata.GridTitle = "My Grid Title"

    //get the template the data will be loaded into
    t1, err := template.ParseFiles("template.html")
    if t1 == nil {
        fmt.Println("File Not Found: ", err)
    }
    //load the template with data and display
    terr := t1.Execute(w, &wdata)
    if terr != nil {
        fmt.Println("terr: ", terr)
    }

    db = db.Unsafe()
    defer db.Close()

}


func main() {
    http.HandleFunc("/",ConsoleHandler)
}

Here is my template.html

<html>
<head><title>{{.Title}}</title></head><body>
...
<h1>{{.Heading}}</h1>
    <div id="gridviewcontainer">
    <br />
    <div id="gridtitle">
        <a href="{{.GridTitleLink}}" style="font-size:25px;">{{.GridTitle}}</a>
    </div>
    <table id="gridtable">
    <tr>{{range $ColumnIdx, $colheading := .ColumnHeading}}
    <th>{{$colheading}}</th>{{end}}</tr>
<<!---This is what is causing the issue, .NumOfRows is not a valid field, must be array, channel, pipeline, or map --> 
    {{range $index, $rowval := .NumOfRows}}
        <tr>
        {{range $rowidx, $rowdat := .RowData}}<td>{{$rowdat}}</td>{{end}}
        </tr>
        {{endfor}}
    </table>

...
</body>
</html>

I connect to the database correctly and using the "fmt" package I can print correctly. But I can't figure out how to loop through for number of rows retured in the html page. Is there a way to cast sql.Rows to a correct type or loop for a set integer number of times in html.

ps. I tried using {{ $index := 3}}...{end}} in the html, but that didn't work

Any input would be greatly appreciated

  • 写回答

1条回答 默认 最新

  • dongtuo5262 2015-02-17 18:40
    关注

    At the start of a new row, insert a "NewRow" string to serve as a flag in the html. Then in the {{range $rowidx, $rowdat := .RowData}} loop add an if statement that ends and starts a new row if $rowdat == "NewRow"

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?