From bd07add64ea830f7db47fddb7b748adffef077b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Z=C3=BCrcher?= Date: Tue, 6 Jan 2026 09:54:47 +0100 Subject: [PATCH] add function convert html --- converter/converter.go | 53 +++++++++++++++++++++++++++++++++++++ html2pdf_test.go | 60 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/converter/converter.go b/converter/converter.go index f0ae2a1..6639a4f 100644 --- a/converter/converter.go +++ b/converter/converter.go @@ -126,6 +126,59 @@ func (c *Converter) Convert(files ...models.File) error { return nil } +// Convert converts all given input files +func (c *Converter) ConvertHtml(html []byte, outputPath string) error { + + if len(html) == 0 { + return fmt.Errorf("no .html input provided") + } else if outputPath == "" || filepath.Ext(outputPath) != ".pdf" { + return fmt.Errorf("no .pdf output file path provided: %s", outputPath) + } + + taskCtx, taskCancel := chromedp.NewContext(c.browserCtx) + timeoutCtx, timeoutCancel := context.WithTimeout(taskCtx, 60*time.Second) + + var pdfData []byte + err := chromedp.Run(timeoutCtx, + // Start with a blank page + chromedp.Navigate("about:blank"), + // Inject HTML directly + chromedp.ActionFunc(func(ctx context.Context) error { + frameTree, err := page.GetFrameTree().Do(ctx) + if err != nil { + return err + } + + return page.SetDocumentContent(frameTree.Frame.ID, string(html)).Do(ctx) + }), + chromedp.WaitReady("body", chromedp.ByQuery), + chromedp.ActionFunc(func(ctx context.Context) error { + buf, _, err := page.PrintToPDF(). + WithPrintBackground(true). + WithPaperWidth(8.27). + WithPaperHeight(11.69). + Do(ctx) + if err != nil { + return err + } + pdfData = buf + return nil + }), + ) + + timeoutCancel() + taskCancel() + if err != nil { + return err + } + + // Save PDF to file + if err := os.WriteFile(outputPath, pdfData, 0644); err != nil { + return err + } + return nil +} + func (c *Converter) Close() { // Close browser first, then allocator if c.browserCancel != nil { diff --git a/html2pdf_test.go b/html2pdf_test.go index c3cb1d6..72670cb 100644 --- a/html2pdf_test.go +++ b/html2pdf_test.go @@ -1,6 +1,7 @@ package html2pdf import ( + "bytes" "fmt" "os" "path/filepath" @@ -57,3 +58,62 @@ func TestConvertFiles(t *testing.T) { } t.Log("test successfull") } + +func TestConvertHtml(t *testing.T) { + t.Log("start test ConvertHtml") + + // Skip in short mode (useful for CI) + if testing.Short() { + t.Skip("skipping ConvertHtml integration test in short mode") + } + + html := []byte(` + + + + + Test PDF + + + +

Hello PDF

+

This is a test.

+ + +`) + + tmpDir := t.TempDir() + outputPath := filepath.Join(tmpDir, "test.pdf") + + c, err := converter.NewConverter("assets/chrome-headless-shell/win64") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + err = c.ConvertHtml(html, outputPath) + if err != nil { + t.Fatalf("ConvertHtml failed: %v", err) + } + + // Assert PDF exists + data, err := os.ReadFile(outputPath) + if err != nil { + t.Fatalf("PDF not created: %v", err) + } + + // Assert non-empty + if len(data) == 0 { + t.Fatal("PDF file is empty") + } + + // Assert valid PDF header + if !bytes.HasPrefix(data, []byte("%PDF-")) { + t.Fatalf("output is not a valid PDF (missing %%PDF- header)") + } + + t.Log("ConvertHtml test successful") +}