好,所以我是Echo框架的Go Lang,尝试构建pdf,它将从数据库源中加载数据-稍后再介绍。
这就是我渲染pdf html
布局的方式,
func (c *Controller) DataTest(ec echo.Context) error {
return ec.Render(http.StatusOK, "pdf.html", map[string]interface{}{
"name": "TEST",
"msg": "Hello, XXXX!",
})
}
上面的函数工作正常,并呈现html(我为该函数构建了一个临时路径)。现在,我想使用该函数作为html模板来构建pdf。
所以我正在使用wkhtmltopdf
和lib "github.com/SebastiaanKlippert/go-wkhtmltopdf"
这就是我在pdf中呈现html的方式,
html, err := ioutil.ReadFile("./assets/pdf.html")
if err != nil {
return err
}
但是我需要能够更新模板,所以这就是为什么我尝试呈现页面并将其带入pdf的原因。
但是,Echo框架返回一个错误类型,而不是字节或字符串类型,我不确定如何更新它,以便将渲染的内容作为字节返回。
谢谢
更新
page := wkhtmltopdf.NewPageReader(bytes.NewReader(c.DataTest(data)))
这是我当前的工作方式,数据只是一个html字符串,然后将其转换为NewReader
的一个字节片。
这很好,但是我想通过Echo将DataTest
函数转换为完全呈现的html页面。这样做的问题是,当您返回呈现的页面时,该页面将作为错误类型返回。
所以我试图找出更新原因,所以我可以将数据作为html字符串返回,然后将其作为字节片放入。
答案 0 :(得分:0)
据我所知,您想要做
因此,Echo返回error
的原因是实际上它不仅完成模板渲染,而且还向客户端发送响应。如果要在两者之间做其他事情,则不能从echo中使用该方法。
幸运的是,echo并没有做任何神奇的事情。您可以只使用具有相同结果的标准模板包。
func GetHtml(filename string, data interface{}) (string, error) {
filedata, err := ioutil.ReadFile(filename)
if err != nil {
return "", err
}
asString := string(filedata)
t, err := template.New("any-name").Parse(asString)
if err != nil {
return "", err
}
var buffer bytes.Buffer
err = t.Execute(&buffer, data)
if err != nil {
return "", err
}
return buffer.String(), nil
}
您有返回string
的函数。如果可以的话,可以使用buffer.Bytes()
来拥有字节数组。
此后,您可以做任何事情,例如转换为PDF并使用echoCtx.Response().Writer()
写回客户端。
希望有帮助,但是将来尝试提出更精确的问题,那么您更有可能收到准确的答复。
答案 1 :(得分:0)
如果要呈现html,请使用echo的自定义中间件。希望对您有帮助。
main.go
package main
import (
"bufio"
"bytes"
"errors"
"fmt"
"html/template"
"io"
"net"
"net/http"
"github.com/labstack/echo"
)
type TemplateRegistry struct {
templates map[string]*template.Template
}
func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
tmpl, ok := t.templates[name]
if !ok {
err := errors.New("Template not found -> " + name)
return err
}
return tmpl.ExecuteTemplate(w, "base.html", data)
}
func main() {
e := echo.New()
templates := make(map[string]*template.Template)
templates["about.html"] = template.Must(template.ParseFiles("view/about.html", "view/base.html"))
e.Renderer = &TemplateRegistry{
templates: templates,
}
// add custom middleware
// e.Use(PdfMiddleware)
// only AboutHandler for Pdf
e.GET("/about", PdfMiddleware(AboutHandler))
// Start the Echo server
e.Logger.Fatal(e.Start(":8080"))
}
// custom middleware
func PdfMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) (err error) {
resBody := new(bytes.Buffer)
mw := io.MultiWriter(c.Response().Writer, resBody)
writer := &bodyDumpResponseWriter{Writer: mw, ResponseWriter: c.Response().Writer}
c.Response().Writer = writer
if err = next(c); err != nil {
c.Error(err)
}
// or use resBody.Bytes()
fmt.Println(resBody.String())
return
}
}
type bodyDumpResponseWriter struct {
io.Writer
http.ResponseWriter
}
func (w *bodyDumpResponseWriter) WriteHeader(code int) {
w.ResponseWriter.WriteHeader(code)
}
func (w *bodyDumpResponseWriter) Write(b []byte) (int, error) {
return w.Writer.Write(b)
}
func (w *bodyDumpResponseWriter) Flush() {
w.ResponseWriter.(http.Flusher).Flush()
}
func (w *bodyDumpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return w.ResponseWriter.(http.Hijacker).Hijack()
}
func AboutHandler(c echo.Context) error {
return c.Render(http.StatusOK, "about.html", map[string]interface{}{
"name": "About",
"msg": "All about Boatswain!",
})
}
view / about.html
{{define "title"}}
Boatswain Blog | {{index . "name"}}
{{end}}
{{define "body"}}
<h1>{{index . "msg"}}</h1>
<h2>This is the about page.</h2>
{{end}}
view / base.html
{{define "base.html"}}
<!DOCTYPE html>
<html>
<head>
<title>{{template "title" .}}</title>
</head>
<body>
{{template "body" .}}
</body>
</html>
{{end}}