pdf - 如何在创建 pdf 时使用呈现的模板

标签 pdf go

好吧,我是使用 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 的自定义中间件。希望对您有所帮助。

ma​​in.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/

相关文章:

java - 如何在 Apache FOP 中设置全局字体系列?

regex - 如何在 Go 中执行不区分大小写的正则表达式?

go - 如何将一片 Uint64 变成一片字节

javascript - 如何从 iframe 中打印 pdf?

ios - iPad 上可填写的 PDF 表单

json - 在使用 MongoDB 将文档分配给 Go 中的结构之前如何转换文档?

amazon-web-services - 如何使用 AWS SDK for Go 创建 EMR 集群

go - 如何在 Go 中创建 AWS Lambda 来处理多个事件

pdf - ABCPdf 将 Svg 流转换为 PDF

Java:使用 PDFBox 1 库从图像创建 PDF 页面