在golang中从html创建pdf

问题描述 投票:0回答:9

如何从 Google Go 中的 HTML 输入创建 PDF 文件?如果还不可能,是否有任何旨在解决此问题的举措?

我正在寻找像 php 中的 TCPDF 这样的解决方案。

pdf pdf-generation go
9个回答
17
投票

gopdf怎么样(https://github.com/signintech/gopdf)。

看来您正在寻找。


17
投票

安装

go get -u github.com/SebastiaanKlippert/go-wkhtmltopdf

go version go1.9.2 linux/amd64

代码

   import (
        "fmt"
        "strings"
        wkhtml "github.com/SebastiaanKlippert/go-wkhtmltopdf"
    )  
    
      func main(){
                 pdfg, err :=  wkhtml.NewPDFGenerator()
               if err != nil{
                  return
              }
              htmlStr := `<html><body><h1 style="color:red;">This is an html
 from pdf to test color<h1><img src="http://api.qrserver.com/v1/create-qr-
code/?data=HelloWorld" alt="img" height="42" width="42"></img></body></html>`
            
              pdfg.AddPage(wkhtml.NewPageReader(strings.NewReader(htmlStr)))
            
   
              // Create PDF document in internal buffer
              err = pdfg.Create()
              if err != nil {
                  log.Fatal(err)
              }
            
               //Your Pdf Name
               err = pdfg.WriteFile("./Your_pdfname.pdf")
              if err != nil {
                  log.Fatal(err)
              }
            
              fmt.Println("Done")
        }

上面的代码适用于在 golang 中将 html 转换为 pdf,并具有适当的背景图像和嵌入式 Css 样式标签

检查仓库

请参阅拉取请求文档改进

建议(来自https://wkhtmltopdf.org/status.html):

请勿将 wkhtmltopdf 与任何不受信任的 HTML 一起使用 - 请务必清理任何用户提供的 HTML/JS,否则可能会导致其运行的服务器被完全接管!请考虑使用强制访问控制系统,如 AppArmor 或 SELinux,请参阅推荐的 AppArmor 策略。

如果您使用它来生成报告(即使用您控制的 HTML),还可以考虑使用 WeasyPrint 或商业工具 Prince - 请注意,我不隶属于这两个项目,请尽自己的努力。

如果您使用它来转换使用动态 JS 的网站,请考虑使用 puppeteer 或其具有的众多包装器之一。


7
投票

还有这个包wkhtmltopdf-go,它使用了libwkhtmltox库。但我不确定它有多稳定。


7
投票

功能

page.PrintToPDF()
效果很好。

这是一个将其与 chromedp 一起使用的示例 (

go get -u github.com/chromedp/chromedp
):

import (
    "context"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"
    "time"

    "github.com/chromedp/cdproto/emulation"
    "github.com/chromedp/cdproto/page"
    "github.com/chromedp/chromedp"
)

func main() {
        taskCtx, cancel := chromedp.NewContext(
            context.Background(),
            chromedp.WithLogf(log.Printf),
        )
        defer cancel()
        var pdfBuffer []byte
        if err := chromedp.Run(taskCtx, pdfGrabber("https://www.wikipedia.org", "body", &pdfBuffer)); err != nil {
            log.Fatal(err)
        }
        if err := ioutil.WriteFile("coolsite.pdf", pdfBuffer, 0644); err != nil {
            log.Fatal(err)
        }
}

func pdfGrabber(url string, sel string, res *[]byte) chromedp.Tasks {

    start := time.Now()
    return chromedp.Tasks{
        emulation.SetUserAgentOverride("WebScraper 1.0"),
        chromedp.Navigate(url),
        // wait for footer element is visible (ie, page is loaded)
        // chromedp.ScrollIntoView(`footer`),
        chromedp.WaitVisible(`body`, chromedp.ByQuery),
        // chromedp.Text(`h1`, &res, chromedp.NodeVisible, chromedp.ByQuery),
        chromedp.ActionFunc(func(ctx context.Context) error {
            buf, _, err := page.PrintToPDF().WithPrintBackground(true).Do(ctx)
            if err != nil {
                return err
            }
            *res = buf
            //fmt.Printf("h1 contains: '%s'\n", res)
            fmt.Printf("\nTook: %f secs\n", time.Since(start).Seconds())
            return nil
        }),
    }
}

上面将在 chrome headless 中加载 wikipedia.org 并等待正文显示,然后将其另存为 pdf。

终端结果:

$ go run main.go
https://www.wikipedia.org
Scraping url now...

Took: 2.772797 secs

4
投票

我认为我不理解您的要求。由于 HTML 是一种标记语言,因此它需要上下文来呈现(CSS 和屏幕尺寸)。我见过的现有实现通常在无头浏览器中打开页面并以这种方式创建 PDF。

就我个人而言,我只会使用现有的包并从 Go 中删除。 这个看起来不错;甚至在这个答案中推荐。

如果您真的决定在 Go 中实现这一切,请查看 这个 WebKit 包装器。我不确定您会使用什么来生成 PDF,但至少这是一个开始。


3
投票

我正在创建一个替代库,以更简单的方式创建 PDF (https://github.com/johnfercher/maroto)。它使用 gofpdf 并具有网格系统和一些组件,例如 Bootstrap


1
投票

另一个选择是雅典娜。它有一个用 Go 编写的微服务,也可以用作 CLI。


0
投票

我刚刚在 gpt 的帮助下编写了一个库,对于简单的 HTML 来说效率更高:https://github.com/html2any/layout。你可以试试


-4
投票

另一个选项是 UniHTML(基于容器的 API),它与 UniPDF 互操作,这对于创建 PDF 报告等基于 HTML 模板非常有用。

它在容器中使用headless-chrome引擎,因此渲染非常完美并且具有所有HTML功能。与 UniPDF 的结合提供了额外的优势,例如自动生成目录、大纲等。以及添加密码保护、添加 PDF 表单、数字签名等的能力。

要为磁盘上的 HTML 模板创建 PDF,可以通过以下方式完成:

package main

import (
    "fmt"
    "os"

    "github.com/unidoc/unihtml"
    "github.com/unidoc/unipdf/v3/common/license"
    "github.com/unidoc/unipdf/v3/creator"
)

func main() {
    // Set the UniDoc license.
    if err := license.SetMeteredKey("my api key goes here"); err != nil {
        fmt.Printf("Err: setting metered key failed: %v\n", err)
        os.Exit(1)
    }

    // Establish connection with the UniHTML Server.
    if err := unihtml.Connect(":8080"); err != nil {
        fmt.Printf("Err:  Connect failed: %v\n", err)
        os.Exit(1)
    }

    // Get new PDF Creator.
    c := creator.New()

    // AddTOC enables Table of Contents generation.
    c.AddTOC = true

    chapter := c.NewChapter("Points")

    // Read the content of the sample.html file and load it to the conversion.
    htmlDocument, err := unihtml.NewDocument("sample.html")
    if err != nil {
        fmt.Printf("Err: NewDocument failed: %v\n", err)
        os.Exit(1)
    }

    // Draw the html document file in the context of the creator.
    if err = chapter.Add(htmlDocument); err != nil {
        fmt.Printf("Err: Draw failed: %v\n", err)
        os.Exit(1)
    }

    if err = c.Draw(chapter); err != nil {
        fmt.Printf("Err: Draw failed: %v\n", err)
        os.Exit(1)
    }


    // Write the result file to PDF.
    if err = c.WriteToFile("sample.pdf"); err != nil {
        fmt.Printf("Err: %v\n", err)
        os.Exit(1)
    }
}

我在[此处]写了一篇 UniHTML 介绍文章,如果需要更多信息,该文章可能会很有用 (https://www.unidoc.io/post/html-for-pdf-reports-in-go)。

披露:我是UniPDF的原始开发者。

© www.soinside.com 2019 - 2024. All rights reserved.