好吧,我是使用 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
和库 "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
的 byte slice 段。
这工作正常,但我想通过 Echo 将 DataTest
函数转换为完全呈现的 html 页面。问题在于,当您返回呈现的页面时,它会作为错误类型返回。
所以我试图找出更新它的原因,这样我就可以将数据作为 html 字符串返回,然后将其作为 byte slice 段放入。
最佳答案
如果您想要呈现 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}}
关于pdf - 如何在创建 pdf 时使用呈现的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55100071/