Skip to content

Instantly share code, notes, and snippets.

@jerbob92
Last active June 28, 2023 19:57
Show Gist options
  • Save jerbob92/b3d94530944ec5e69f71a7dacbb6e695 to your computer and use it in GitHub Desktop.
Save jerbob92/b3d94530944ec5e69f71a7dacbb6e695 to your computer and use it in GitHub Desktop.
go-pdfium webserver example
package main
import (
"fmt"
"mime/multipart"
"net/http"
"time"
"github.com/klippa-app/go-pdfium"
"github.com/klippa-app/go-pdfium/multi_threaded"
"github.com/klippa-app/go-pdfium/requests"
"github.com/gin-gonic/gin"
)
// Be sure to close pools/instances when you're done with them.
var pool pdfium.Pool
func init() {
// Init the PDFium library and return the instance to open documents.
// You can tweak these configs to your need. Be aware that workers can use quite some memory.
pool = multi_threaded.Init(multi_threaded.Config{
MinIdle: 4, // Makes sure that at least x workers are always available
MaxIdle: 4, // Makes sure that at most x workers are ever available
MaxTotal: 4, // Maxium amount of workers in total, allows the amount of workers to grow when needed, items between total max and idle max are automatically cleaned up, while idle workers are kept alive so they can be used directly.
Command: multi_threaded.Command{
BinPath: "go", // Only do this while developing, on production put the actual binary path in here. You should not want the Go runtime on production.
Args: []string{"run", "worker/main.go"}, // This is a reference to the worker package, this can be left empty when using a direct binary path.
},
})
}
type BindFile struct {
DPI int `form:"dpi" binding:"required"`
File *multipart.FileHeader `form:"file" binding:"required"`
}
func main() {
r := gin.Default()
r.POST("/render", func(c *gin.Context) {
var bindFile BindFile
if err := c.ShouldBind(&bindFile); err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("err: %s", err.Error()))
return
}
src, err := bindFile.File.Open()
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("upload file err: %s", err.Error()))
return
}
defer src.Close()
pdfiumInstance, err := pool.GetInstance(time.Second * 30)
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("pdfium err: %s", err.Error()))
return
}
defer pdfiumInstance.Close()
doc, err := pdfiumInstance.OpenDocument(&requests.OpenDocument{
FileReader: src,
})
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("pdfium err: %s", err.Error()))
return
}
renderedPages, err := pdfiumInstance.RenderToFile(&requests.RenderToFile{
RenderPagesInDPI: &requests.RenderPagesInDPI{
Pages: []requests.RenderPageInDPI{
{
Page: requests.Page{
ByIndex: &requests.PageByIndex{
Document: doc.Document,
Index: 0,
},
},
DPI: bindFile.DPI,
},
},
},
OutputFormat: requests.RenderToFileOutputFormatJPG,
OutputTarget: requests.RenderToFileOutputTargetBytes,
})
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("pdfium err: %s", err.Error()))
return
}
c.Data(200, "image/jpeg", *renderedPages.ImageBytes)
})
r.Run(":8082") // listen and serve on 0.0.0.0:8082 (for windows "localhost:8082")
}
package main
import "github.com/klippa-app/go-pdfium/multi_threaded/worker"
func main() {
worker.StartWorker(nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment