日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go 导出 html 报告(使用 hero 预编译 html 模板引擎)

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go 导出 html 报告(使用 hero 预编译 html 模板引擎) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

項目需求,需要將服務器的數據進行導出,方便攜帶展示,做了一次 html 報告的導出,考慮如何實現。

  • 使用 vue 等前端框架,將數據導出成一個個的 json 文件,然后通過讀取 js 來動態渲染 html 視圖
  • 直接將數據寫入 html 頁面,多導出一些 html,通過 iframe 來進行頁面的加載
  • 這里使用的是第二種方式。

    本篇主要介紹一下 go 的一個開源庫 hero 預編譯模板引擎,用于快速的渲染 html。

    常見的模板引擎一般有兩種實現方式,一種是直接解析 HTML 語法樹,然后根據一定的規則動態的拼接,另外一種是把模板預先生成代碼,渲染模板時調用相關的函數即可。

    go 官方內置的 template 包是第一種實現方式,本篇的主角用的是第二種。

    hero 簡介

    可以直接去 github 上看,這里做一個簡短的介紹。

    安裝

    go get github.com/shiyanhui/hero go get github.com/shiyanhui/hero/hero// Hero需要goimports處理生成的go代碼,所以需要安裝goimports. go get golang.org/x/tools/cmd/goimports

    使用

    hero [options]options:- source: 模板目錄,默認為當前目錄- dest: 生成的go代碼的目錄,如果沒有設置的話,和source一樣- pkgname: 生成的go代碼包的名稱,默認為template- extensions: source文件的后綴, 如果有多個則用英文逗號隔開, 默認為.html- watch: 是否監控模板文件改動并自動編譯example:hero -source="./"hero -source="$GOPATH/src/app/template" -watch

    基本語法

    Hero 總共有九種語句,他們分別是:

    • 函數定義語句 <%: func define %>

      • 該語句定義了該模板所對應的函數,如果一個模板中沒有函數定義語句,那么最終結果不會生成對應的函數。
      • 該函數最后一個參數必須為*bytes.Buffer或者io.Writer, hero會自動識別該參數的名字,并把把結果寫到該參數里。
      • 例:
        • <%: func UserList(userList []string, buffer *bytes.Buffer) %>
        • <%: func UserList(userList []string, w io.Writer) %>
        • <%: func UserList(userList []string, w io.Writer) (int, error) %>
    • 模板繼承語句 <%~ "parent template" %>

      • 該語句聲明要繼承的模板。
      • 例: <%~ "index.html" >
    • 模板include語句 <%+ "sub template" %>

      • 該語句把要include的模板加載進該模板,工作原理和C++中的#include有點類似。
      • 例: <%+ "user.html" >
    • 包導入語句 <%! go code %>

      • 該語句用來聲明所有在函數外的代碼,包括依賴包導入、全局變量、const等。

      • 該語句不會被子模板所繼承

      • 例:

        <%!import ("fmt""strings")var a intconst b = "hello, world"func Add(a, b int) int {return a + b}type S struct {Name string}func (s S) String() string {return s.Name} %>
    • 塊語句 <%@ blockName { %> <% } %>

      • 塊語句是用來在子模板中重寫父模中的同名塊,進而實現模板的繼承。

      • 例:

        <!DOCTYPE html> <html><head><meta charset="utf-8"></head><body><%@ body { %><% } %></body> </html>
    • Go代碼語句 <% go code %>

      • 該語句定義了函數內部的代碼部分。

      • 例:

        <% for _, user := range userList { %><% if user != "Alice" { %><%= user %><% } %> <% } %><%a, b := 1, 2c := Add(a, b) %>
    • 原生值語句 <%==[t] variable %>

      • 該語句把變量轉換為string。

      • t是變量的類型,hero會自動根據t來選擇轉換函數。t的待選值有:

        • b: bool
        • i: int, int8, int16, int32, int64
        • u: byte, uint, uint8, uint16, uint32, uint64
        • f: float32, float64
        • s: string
        • bs: []byte
        • v: interface

        注意:

        • 如果t沒有設置,那么t默認為s.
        • 最好不要使用v,因為其對應的轉換函數為fmt.Sprintf("%v", variable),該函數很慢。
      • 例:

        <%== "hello" %> <%==i 34 %> <%==u Add(a, b) %> <%==s user.Name %>
    • 轉義值語句 <%= statement %>

      • 該語句把變量轉換為string后,又通過html.EscapesString記性轉義。

      • t跟上面原生值語句中的t一樣。

      • 例:

        <%= a %> <%= a + b %> <%= Add(a, b) %> <%= user.Name %>
    • 注釋語句 <%# note %>

      • 該語句注釋相關模板,注釋不會被生成到go代碼里邊去。
      • 例: <# 這是一個注釋 >.

    原理

    最終生成的代碼,就是通過字符串拼接,寫入 io.Writer。下面是一個例子,生成后的代碼如下:

    func WriteTreeNodeHtml(param *RenderTemplateParam, w io.Writer) {_buffer := hero.GetBuffer()defer hero.PutBuffer(_buffer)_buffer.WriteString(`<html><head><meta charset="utf-8" /><link rel="stylesheet" href="css/build.css" /><link rel="stylesheet" href="css/jquery.treeview.css" /><link rel="stylesheet" href="css/screen.css" /><script src="js/jquery.min.js"></script><script src="js/jquery.cookie.js"></script><script src="js/jquery.treeview.js" type="text/javascript"></script><script type="text/javascript">$(function() {$("#tree").treeview({collapsed: true,animated: "fast",control: "#sidetreecontrol",prerendered: true,persist: "location"});})</script></head><body style="margin: 10px;"><div><h3>`)hero.EscapeHTML(GetAppName(), _buffer)_buffer.WriteString(`報告</h3><div id=jstree style="font-size:14px"><ul class="treeview" id="tree" style="margin-top:6px;"><li><a class="jstree-anchor" href="page1.html#case" target="pageframe"><i style="margin-left: 4px;margin-right: 4px;" class="icon-file iconfont"></i>案件</a></li><li><a class="jstree-anchor" href="page1.html#evidences" target="pageframe"><i style="margin-left: 4px;margin-right: 4px;" class="icon-evidence iconfont"></i>檢材信息</a></li><li><a class="jstree-anchor" href="page1.html#brief" target="pageframe"><i style="margin-left: 4px;margin-right: 4px;" class="icon-evidence iconfont"></i>數據統計文字概括</a></li><li><a class="jstree-anchor" href="page1.html#summary" target="pageframe"><i style="margin-left: 4px;margin-right: 4px;" class="icon-summary iconfont"></i>數據統計清單</a></li>`)treeNodes, ok := param.Data.([]*ReportTreeNode)if !ok {return}for _, node := range treeNodes {GenerateTreeNode(node, _buffer)}_buffer.WriteString(`</ul></div></div></body> </html>`)w.Write(_buffer.Bytes())}

    總結

    使用 go 生成 html,原理很簡單,通過字符串拼接,將數據都寫入對應的地方即可。麻煩的點就在于 html 頁面的布局和數據的插入對應。

    參考

    https://github.com/shiyanhui/hero

    總結

    以上是生活随笔為你收集整理的go 导出 html 报告(使用 hero 预编译 html 模板引擎)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。