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.
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.