英文:
Go ChromeDP ignores any external or internal css during printing to pdf and uses only those, that in html file ONLY
问题
Go ChromeDP不使用任何CSS,无论是内部还是外部样式(只使用在HTML中编写的样式,不使用其他文件)。我使用以下方法将HTML文件添加到chromedp中:
page.SetDocumentContent(frameTree.Frame.ID, string(buf.Bytes())).Do(ctx)
然后使用以下代码将其转换为PDF:
buf, _, err := page.PrintToPDF().Do(ctx)
if err != nil {
return err
}
_, err = outputBuf.Write(buf)
if err != nil {
return err
}
但是生成的PDF没有样式(即使使用外部CSS文件服务器)。我尝试使用page.GetResourceTree().Do(ctx)
+ css.CreateStyleSheet(resourceTree.Frame.ID).Do(ctx)
来添加CSS,并使用以下代码设置样式:
css.SetStyleSheetText(stylesheet, `.c {
color: red;
font-size: 30px;
background-color: aqua;
}`).Do(ctx)
这样可以工作,但是每次生成PDF时都需要这样做,特别是在使用html/template的情况下。也许有一种简单的方法可以将外部CSS添加到单个HTML文件中。你觉得呢?
谢谢任何回答。
Bohdan
我想使用chromedp将带有外部CSS、图像和字体的Go模板转换为PDF,但它忽略了主HTML文件之外的任何内容。
英文:
Go ChromeDP not using any css either internal or external styles (only those, that was written in html, not other file). I using method
page.SetDocumentContent(frameTree.Frame.ID, string(buf.Bytes())).Do(ctx)
to add html file to chromedp, and
buf, _, err: = page.PrintToPDF().Do(ctx)
if err != nil {
return err
}
_, err = outputBuf.Write(buf)
if err != nil {
return err
}
to print to pdf, but pdf in result not styled (even with external css fileserver). I tried to add it with page.GetResourceTree().Do(ctx)
+ css.CreateStyleSheet(resourceTree.Frame.ID).Do(ctx)
+
css.SetStyleSheetText(stylesheet, `.c {
color: red;
font-size: 30px;
background-color: aqua;
}
`).Do(ctx)
and it worked, but it sad to use it every time I want generate pdf, especially in my case, because I am using html from html/template. Maybe there are easy way to add external css into single html file? What do you think?
Thanks for any answer
Bohdan
I want to convert go template with external css, images and font into pdf using chromedp, but it ignored anything beyond main html file.
答案1
得分: 4
请注意,外部资源需要时间加载。您应该等待它们加载完成。当页面准备好时,会触发Page.loadEventFired
事件。因此,我们可以等待此事件,然后打印页面。请参考下面的示例代码:
package main
import (
"context"
"fmt"
"log"
"net/http"
"net/http/httptest"
"os"
"sync"
"time"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 模拟网络延迟
time.Sleep(2 * time.Second)
w.Header().Set("Content-Type", "text/css")
fmt.Fprint(w, `h1 {font-size: 100pt; color: red;}`)
}))
defer ts.Close()
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// 构建您的HTML
html := `<html>
<head>
<link rel="stylesheet" href="%s/style.css">
</head>
<body>
<h1> Hello World! </h1>
</body>
</html>
`
var wg sync.WaitGroup
wg.Add(1)
if err := chromedp.Run(ctx,
chromedp.Navigate("about:blank"),
// 设置监听器以监听page.EventLoadEventFired事件
chromedp.ActionFunc(func(ctx context.Context) error {
lctx, cancel := context.WithCancel(ctx)
chromedp.ListenTarget(lctx, func(ev interface{}) {
if _, ok := ev.(*page.EventLoadEventFired); ok {
wg.Done()
// 移除事件监听器
cancel()
}
})
return nil
}),
chromedp.ActionFunc(func(ctx context.Context) error {
frameTree, err := page.GetFrameTree().Do(ctx)
if err != nil {
return err
}
return page.SetDocumentContent(frameTree.Frame.ID, fmt.Sprintf(html, ts.URL)).Do(ctx)
}),
// 等待page.EventLoadEventFired事件
chromedp.ActionFunc(func(ctx context.Context) error {
wg.Wait()
return nil
}),
chromedp.ActionFunc(func(ctx context.Context) error {
buf, _, err := page.PrintToPDF().Do(ctx)
if err != nil {
return err
}
return os.WriteFile("sample.pdf", buf, 0644)
}),
); err != nil {
log.Fatal(err)
}
log.Println("完成!")
}
参考:https://github.com/chromedp/chromedp/issues/1152.
英文:
Please note that external resources take time to load. You should wait for them to be loaded. When the page is ready, the Page.loadEventFired
event is raised. So we can wait for this event and print the page afterward. See the demo below:
package main
import (
"context"
"fmt"
"log"
"net/http"
"net/http/httptest"
"os"
"sync"
"time"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Simulate a network latency.
time.Sleep(2 * time.Second)
w.Header().Set("Content-Type", "text/css")
fmt.Fprint(w, `h1 {font-size: 100pt; color: red;}`)
}))
defer ts.Close()
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// construct your html
html := `<html>
<head>
<link rel="stylesheet" href="%s/style.css">
</head>
<body>
<h1> Hello World! </h1>
</body>
</html>
`
var wg sync.WaitGroup
wg.Add(1)
if err := chromedp.Run(ctx,
chromedp.Navigate("about:blank"),
// setup the listener to listen for the page.EventLoadEventFired
chromedp.ActionFunc(func(ctx context.Context) error {
lctx, cancel := context.WithCancel(ctx)
chromedp.ListenTarget(lctx, func(ev interface{}) {
if _, ok := ev.(*page.EventLoadEventFired); ok {
wg.Done()
// remove the event listener
cancel()
}
})
return nil
}),
chromedp.ActionFunc(func(ctx context.Context) error {
frameTree, err := page.GetFrameTree().Do(ctx)
if err != nil {
return err
}
return page.SetDocumentContent(frameTree.Frame.ID, fmt.Sprintf(html, ts.URL)).Do(ctx)
}),
// wait for page.EventLoadEventFired
chromedp.ActionFunc(func(ctx context.Context) error {
wg.Wait()
return nil
}),
chromedp.ActionFunc(func(ctx context.Context) error {
buf, _, err := page.PrintToPDF().Do(ctx)
if err != nil {
return err
}
return os.WriteFile("sample.pdf", buf, 0644)
}),
); err != nil {
log.Fatal(err)
}
log.Println("done!")
}
Reference: https://github.com/chromedp/chromedp/issues/1152.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论