feat(services): Implement pdf conversion through gotenberg

This commit is contained in:
Nicolai Ort 2024-12-03 16:25:17 +01:00
parent f4f5c8b63a
commit 382a799038
Signed by: niggl
GPG Key ID: 13AFA55AF62F269F

107
services/converter.go Normal file
View File

@ -0,0 +1,107 @@
package services
import (
"bytes"
"fmt"
"mime/multipart"
"net/http"
"strconv"
"github.com/oxplot/papersizes"
)
type Converter interface {
ToPdf(html string, pageSize string, landscape bool) ([]byte, error)
}
type GotenbergConverter struct {
BaseUrl string
}
func (g *GotenbergConverter) ToPdf(html string, pageSize string, landscape bool) ([]byte, error) {
client := &http.Client{}
defer client.CloseIdleConnections()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("files", "index.html")
if err != nil {
return nil, err
}
_, err = part.Write([]byte(html))
if err != nil {
return nil, err
}
size := papersizes.FromName(pageSize)
if size == nil {
return nil, fmt.Errorf("invalid page size: %s", pageSize)
}
err = writer.WriteField("paperWidth", strconv.Itoa(size.Width)+"mm")
if err != nil {
return nil, err
}
err = writer.WriteField("paperHeight", strconv.Itoa(size.Height)+"mm")
if err != nil {
return nil, err
}
err = writer.WriteField("landscape", strconv.FormatBool(landscape))
if err != nil {
return nil, err
}
err = writer.WriteField("marginTop", "0")
if err != nil {
return nil, err
}
err = writer.WriteField("marginBottom", "0")
if err != nil {
return nil, err
}
err = writer.WriteField("marginLeft", "0")
if err != nil {
return nil, err
}
err = writer.WriteField("marginRight", "0")
if err != nil {
return nil, err
}
err = writer.WriteField("preferCssPageSize", "true")
if err != nil {
return nil, err
}
err = writer.Close()
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", g.BaseUrl+"/forms/chromium/convert/html", body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
data := new(bytes.Buffer)
_, err = data.ReadFrom(resp.Body)
if err != nil {
return nil, err
}
return data.Bytes(), nil
}