在Golang中从HTML创建PDF

vq8itlhq  于 2023-11-14  发布在  Go
关注(0)|答案(8)|浏览(258)

如何在Google Go中从HTML输入创建PDF文件?如果还不可能,是否有任何旨在解决这个问题的创意?
我正在寻找一个解决方案,如PHP中的TCPDF。

kse8i1jr

kse8i1jr2#

安装
第一个月
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")
        }

字符串
上述代码适用于将html转换为具有适当背景图像和嵌入式CSS样式标签的golang pdf
Check repo
See Pull request Documentation Improved
推荐(来自https://wkhtmltopdf.org/status.html):
不要将wkhtmltopdf用于任何不受信任的HTML -请确保清理任何用户提供的HTML/JS,否则可能会导致其运行的服务器完全接管!请考虑使用强制访问控制系统,如AppArmor或SELinux,请参阅推荐的AppArmor策略。
如果你用它来生成报告(比如你控制的HTML),也可以考虑使用WeasyPrint或商业工具Prince --请注意,我与这两个项目都没有关系,请尽你的努力。
如果你用它来转换一个使用动态JS的网站,考虑使用puppeteer或它的许多 Package 器之一。

a0x5cqrl

a0x5cqrl3#

还有一个软件包wkhtmltopdf-go,它使用了libwkhtmltox库,不过我不确定它有多稳定。

ia2d9nvy

ia2d9nvy4#

函数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中无头加载wikipedia.org,等待body出现,然后保存为pdf。
终端结果:

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

Took: 2.772797 secs

ndh0cuux

ndh0cuux5#

我想我不明白你的要求。由于HTML是一种标记语言,它需要上下文来呈现(CSS和屏幕大小)。我见过的现有实现通常在无头浏览器中打开页面并以这种方式创建PDF。
就我个人而言,我只会使用Go中现有的包和shell。This one看起来不错;它甚至在this answer中被推荐。
如果你真的决定在Go中实现这一切,看看this WebKit wrapper。我不确定你会用什么来生成PDF,但至少这是一个开始。

v7pvogib

v7pvogib6#

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

093gszye

093gszye7#

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

omjgkv6w

omjgkv6w8#

另一个选项是UniHTML(基于容器的API),它与UniPDF互操作,这对于基于HTML模板创建PDF报告等非常有用。
它在容器中使用无头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的原始开发人员。

相关问题