如何从 Google Go 中的 HTML 输入创建 PDF 文件?如果还不可能,是否有任何旨在解决此问题的举措?
我正在寻找像 php 中的 TCPDF 这样的解决方案。
gopdf怎么样(https://github.com/signintech/gopdf)。
看来您正在寻找。
安装
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 或其具有的众多包装器之一。
还有这个包wkhtmltopdf-go,它使用了libwkhtmltox库。但我不确定它有多稳定。
功能
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
我认为我不理解您的要求。由于 HTML 是一种标记语言,因此它需要上下文来呈现(CSS 和屏幕尺寸)。我见过的现有实现通常在无头浏览器中打开页面并以这种方式创建 PDF。
就我个人而言,我只会使用现有的包并从 Go 中删除。 这个看起来不错;甚至在这个答案中推荐。
如果您真的决定在 Go 中实现这一切,请查看 这个 WebKit 包装器。我不确定您会使用什么来生成 PDF,但至少这是一个开始。
我正在创建一个替代库,以更简单的方式创建 PDF (https://github.com/johnfercher/maroto)。它使用 gofpdf 并具有网格系统和一些组件,例如 Bootstrap。
另一个选择是雅典娜。它有一个用 Go 编写的微服务,也可以用作 CLI。
我刚刚在 gpt 的帮助下编写了一个库,对于简单的 HTML 来说效率更高:https://github.com/html2any/layout。你可以试试
另一个选项是 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的原始开发者。