使用Golang将HTML转换为PDF的方法与实践
使用Golang将HTML转换为PDF的方法与实践 我们需要将HTML转换为PDF,并且要求毫秒级的处理速度。 请问在这方面最好的开源库是什么?
2 回复
更多关于使用Golang将HTML转换为PDF的方法与实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中实现毫秒级HTML转PDF,推荐使用chromedp库,它通过控制Chrome/Chromium浏览器实现高质量转换。以下是示例代码:
package main
import (
"context"
"io/ioutil"
"log"
"time"
"github.com/chromedp/chromedp"
)
func htmlToPDF(htmlContent string, outputPath string) error {
// 创建上下文
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// 设置超时时间
ctx, cancel = context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel()
var pdfBuffer []byte
// 执行转换任务
err := chromedp.Run(ctx,
chromedp.Navigate("about:blank"),
chromedp.ActionFunc(func(ctx context.Context) error {
// 注入HTML内容
frameTree, err := chromedp.FrameTree(ctx)
if err != nil {
return err
}
err = chromedp.Navigate(frameTree.Root.Frame.ID, "data:text/html,"+htmlContent).Do(ctx)
return err
}),
chromedp.Sleep(50*time.Millisecond), // 等待页面渲染
chromedp.ActionFunc(func(ctx context.Context) error {
// 生成PDF
var err error
pdfBuffer, _, err = chromedp.PrintToPDF().
WithPrintBackground(true).
WithPaperWidth(8.27). // A4宽度(英寸)
WithPaperHeight(11.69). // A4高度(英寸)
Do(ctx)
return err
}),
)
if err != nil {
return err
}
// 保存PDF文件
return ioutil.WriteFile(outputPath, pdfBuffer, 0644)
}
func main() {
html := `
<html>
<body>
<h1>测试文档</h1>
<p>这是一个HTML转PDF的测试。</p>
</body>
</html>
`
start := time.Now()
err := htmlToPDF(html, "output.pdf")
elapsed := time.Since(start)
if err != nil {
log.Fatal(err)
}
log.Printf("转换完成,耗时: %v", elapsed)
}
对于更高性能的场景,可以考虑以下优化方案:
- 使用浏览器池:
type BrowserPool struct {
pool chan *chromedp.Ctx
}
func NewBrowserPool(size int) *BrowserPool {
pool := make(chan *chromedp.Ctx, size)
for i := 0; i < size; i++ {
ctx, _ := chromedp.NewContext(context.Background())
pool <- ctx
}
return &BrowserPool{pool: pool}
}
func (bp *BrowserPool) Convert(html string) ([]byte, error) {
ctx := <-bp.pool
defer func() { bp.pool <- ctx }()
// 转换逻辑
return generatePDF(ctx, html)
}
- 预渲染优化:
func preRenderSetup(ctx context.Context) error {
return chromedp.Run(ctx,
chromedp.EmulateViewport(1920, 1080),
chromedp.ActionFunc(func(ctx context.Context) error {
// 预加载字体和样式
return chromedp.Evaluate(`
const style = document.createElement('style');
style.textContent = '@import url("https://fonts.googleapis.com/css2?family=Roboto");';
document.head.appendChild(style);
`, nil).Do(ctx)
}),
)
}
- 并行处理:
func batchConvert(htmls []string) []string {
var wg sync.WaitGroup
results := make([]string, len(htmls))
for i, html := range htmls {
wg.Add(1)
go func(idx int, content string) {
defer wg.Done()
output := fmt.Sprintf("output_%d.pdf", idx)
err := htmlToPDF(content, output)
if err == nil {
results[idx] = output
}
}(i, html)
}
wg.Wait()
return results
}
关键配置参数:
// 性能优化配置
pdfOpts := chromedp.PrintToPDF().
WithPreferCSSPageSize(true).
WithPrintBackground(true).
WithMarginTop(0.4).
WithMarginBottom(0.4).
WithMarginLeft(0.4).
WithMarginRight(0.4).
WithScale(1.0)
chromedp的优势在于:
- 支持现代CSS和JavaScript
- 渲染质量与Chrome浏览器一致
- 可通过无头模式减少资源占用
- 支持并发处理
对于简单的HTML转换,也可以考虑go-wkhtmltopdf,但chromedp在渲染质量和性能方面表现更优。

