You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Golang Chromedp实现PDF下载且不存储到服务器

使用chromedp生成PDF并直接返回给客户端(不存储到服务器)

你当前的代码会将生成的PDF存储在服务器本地,要实现不存服务器直接让客户端下载的需求,只需要调整响应头并直接把PDF字节流返回给浏览器即可,核心修改如下:

关键修改点

  1. 删掉服务器本地存储PDF的os.WriteFile代码块
  2. 替换最后返回JSON的逻辑,设置PDF专属的HTTP响应头
  3. 直接将chromedp生成的PDF字节流写入响应体

修改后的完整代码

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "strconv"

    "github.com/chromedp/chromedp"
    "github.com/chromedp/chromedp/kb"
    "github.com/gin-gonic/gin"
    "github.com/gorilla/sessions"
)

func PDFInvoice(c *gin.Context) {
    session := sessions.Default(c)
    id := c.Params.ByName("id")
    token := session.Get("login_session").(string)

    // 创建chromedp上下文
    ctx, cancel := chromedp.NewContext(context.Background())
    defer cancel()

    // 生成PDF字节流
    var buf []byte
    url := "http://localhost:8080/invoice/" + id + "/" + token
    if err := chromedp.Run(ctx, printToPDF(url, &buf)); err != nil {
        log.Printf("生成PDF失败: %v", err)
        c.AbortWithStatus(http.StatusInternalServerError)
        return
    }

    // 设置响应头,触发浏览器下载PDF
    c.Header("Content-Type", "application/pdf")
    // 自定义下载文件名,比如 invoice-xxx.pdf
    c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"invoice-%s.pdf\"", id))
    c.Header("Content-Length", strconv.Itoa(len(buf)))

    // 直接将PDF字节流返回给客户端
    if _, err := c.Writer.Write(buf); err != nil {
        log.Printf("写入响应体失败: %v", err)
        c.AbortWithStatus(http.StatusInternalServerError)
        return
    }
}

// 生成PDF的工具函数(无需修改)
func printToPDF(urlstr string, res *[]byte) chromedp.Tasks {
    return chromedp.Tasks{
        chromedp.Navigate(urlstr),
        chromedp.ActionFunc(func(ctx context.Context) error {
            buf, _, err := page.PrintToPDF().WithPrintBackground(false).Do(ctx)
            if err != nil {
                return err
            }
            *res = buf
            return nil
        }),
    }
}

代码说明

  • 移除本地存储:彻底删除了os.WriteFile相关代码,不再在服务器磁盘保存PDF文件
  • 响应头配置:
    • Content-Type: application/pdf:告诉浏览器响应内容是PDF格式
    • Content-Disposition: attachment; filename="xxx.pdf":强制触发浏览器的下载行为,同时指定用户下载后的文件名
    • Content-Length:让浏览器提前知晓文件大小,优化下载体验
  • 错误处理优化:把log.Fatal改为打印日志并返回错误状态码,避免单个请求失败导致整个服务崩溃

内容的提问来源于stack exchange,提问作者Shakhawat Hossain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:10:38