Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating PDF files in a loop #38

Open
zaky opened this issue Jul 4, 2023 · 4 comments
Open

Creating PDF files in a loop #38

zaky opened this issue Jul 4, 2023 · 4 comments

Comments

@zaky
Copy link

zaky commented Jul 4, 2023

func main() {
for _, v := range []string{"import1.pdf", "import2.pdf", "import3.pdf"} {
CreatePDFFile("header.html", "footer.html", "content.html", v)
}
}

func CreatePDFFile(header, footer, content, output string) error {
// Initialize library.
if err := pdf.Init(); err != nil {
log.Print("fail init", err)

	return err
}
defer pdf.Destroy()
//Insert the content inside the template
// Create object from URL.
object, err := pdf.NewObject(content)
if err != nil {
	log.Print("fail new object", err)
	return err
}
defer object.Destroy()
object.Header.CustomLocation = header
object.Footer.CustomLocation = footer
converter, err = pdf.NewConverter()
if err != nil {
	log.Print("fail new converter", err)
	return err
}

defer converter.Destroy()

converter.PaperSize = pdf.Letter

// Add created objects to the converter.
converter.Add(object)

// Convert objects and save the output PDF document.
outFile, err := os.Create(output)
if err != nil {
	log.Print("fail create", err)
	return err
}
defer outFile.Close()

// Run converter.
if err := converter.Run(outFile); err != nil {
	log.Print("fail run", err)
	return err
}
return nil

}

Runing this code will create 1 valid file, the first one and two invalid files.

@adrg
Copy link
Owner

adrg commented Jul 4, 2023

Hi @zaky

The library needs to be initialized only once, when the application starts. This should work fine:

package main

import (
	"log"
	"os"

	pdf "github.com/adrg/go-wkhtmltopdf"
)

func main() {
	// Initialize library.
	if err := pdf.Init(); err != nil {
		log.Fatal(err)
	}
	defer pdf.Destroy()

	for _, v := range []string{"import1.pdf", "import2.pdf", "import3.pdf"} {
		if err := CreatePDFFile("header.html", "footer.html", "content.html", v); err != nil {
			log.Fatal(err)
		}
	}
}

func CreatePDFFile(header, footer, content, output string) error {
	// Create object from URLs.
	object, err := pdf.NewObject(content)
	if err != nil {
		return err
	}
	defer object.Destroy()

	object.Header.CustomLocation = header
	object.Footer.CustomLocation = footer

	// Create converter.
	converter, err := pdf.NewConverter()
	if err != nil {
		return err
	}
	defer converter.Destroy()

	converter.PaperSize = pdf.Letter

	// Add created objects to the converter.
	converter.Add(object)

	// Convert objects and save the output PDF document.
	outFile, err := os.Create(output)
	if err != nil {
		return err
	}
	defer outFile.Close()

	// Run converter.
	if err := converter.Run(outFile); err != nil {
		return err
	}

	return nil
}

@zaky
Copy link
Author

zaky commented Jul 4, 2023

Actually the code is part of a web server.
What I fount is that if I put the pdf.init/pdf.destroy in main the first request is working fine but not the following requests.
From the second request the server jut stock.

@adrg
Copy link
Owner

adrg commented Jul 5, 2023

For usage inside goroutines see the Basic web page to PDF conversion server or the Configurable web page to PDF conversion server examples. Issue #3 is also relevant.

The library must be initialized on the main thread and the conversion must be performed on the main thread as well. This is a known limitation of wkhtmltox, not of this package.

@zbykovskyi
Copy link

I suppose, as mentioned in previous comment, this code block

func init() {
	// Set main function to run on the main thread.
	runtime.LockOSThread()
}

in general cases prevents situation with library stuck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants