gofpdi icon indicating copy to clipboard operation
gofpdi copied to clipboard

Unable to import more than one file

Open johan-lejdung opened this issue 2 years ago • 6 comments

If I try to import more than one file the last file imported will be used instead of all other files. This is because the same hash is generated for both files, similarly to what is reported here: https://github.com/phpdave11/gofpdi/issues/33, as mentioned https://github.com/phpdave11/gofpdi/compare/v1.0.12...v1.0.13 seemed to solve it, but not when importing from a stream.

Other issues that seem related:

  • https://github.com/phpdave11/gofpdi/issues/56
  • https://github.com/phpdave11/gofpdi/issues/52

sample code:

importer := gofpdi.NewImporter()
for _, attachment := range msg.Attachments {
   rs := io.ReadSeeker(bytes.NewReader(attachment.Bytes))

   tplID := importer.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
   pdf.AddPage()

   pdf.SetFillColor(238, 238, 238)
   pdf.Rect(0, MarginTop, 210, ContentHeight-MarginTop, "F")

   importer.UseImportedTemplate(pdf, tplID, 0, MarginTop, 0, ContentHeight-MarginTop)
}

similar hashes: Screenshot 2023-03-09 at 09 19 07

In this case i = 1 in both instances of the loop, and this.r.sourcefile = ''. Screenshot 2023-03-09 at 09 22 01

Conclusion:

It seems the code is written to differentiate between filenames, and although each stream is assigned a unique this.sourceFile it is not used in any of the readers of writers. I found that by just setting that name it started working for me.

I'll open up a pull request and hopefully this can get merged.

johan-lejdung avatar Mar 09 '23 08:03 johan-lejdung

Until this is merged into this repository you can use the fixed fork over at https://github.com/chaintraced/gofpdi, just be sure to copy over this file to your repo https://github.com/phpdave11/gofpdf/blob/master/contrib/gofpdi/gofpdi.go but with the import changed to github.com/chaintraced/gofpdi

johan-lejdung avatar Mar 09 '23 08:03 johan-lejdung

@johan-lejdung any example how to use your fork ?

fcarrero avatar Jun 26 '23 19:06 fcarrero

@fcarrero

Copy in the file https://github.com/phpdave11/gofpdf/blob/master/contrib/gofpdi/gofpdi.go and point the import realgofpdi to our repo.

This is the start of the gofpdi_wrap.go (as I chose to call it) file:

/*
Package gofpdi wraps the gofpdi PDF library to import existing PDFs as templates. See github.com/phpdave11/gofpdi
for further information and examples.

Users should call NewImporter() to obtain their own Importer instance to work with.
To retain backwards compatibility, the package offers a default Importer that may be used via global functions. Note
however that use of the default Importer is not thread safe.

ChainTraced NOTE: We're using this file copied from the https://github.com/phpdave11/gofpdf/blob/master/contrib/gofpdi/gofpdi.go
while we wait for our fix detailed here https://github.com/phpdave11/gofpdi/issues/59 to be merged (https://github.com/phpdave11/gofpdi/pull/60).

*/

package pdfgen

import (
	"io"

	realgofpdi "github.com/chaintraced/gofpdi"
)

// gofpdiPdf is a partial interface that only implements the functions we need
// from the PDF generator to put the imported PDF templates on the PDF.
type gofpdiPdf interface {
	ImportObjects(objs map[string][]byte)
	ImportObjPos(objs map[string]map[int]string)
	ImportTemplates(tpls map[string]string)
	UseImportedTemplate(tplName string, x float64, y float64, w float64, h float64)
	SetError(err error)
}

// Importer wraps an Importer from the gofpdi library.
type Importer struct {
	fpdi *realgofpdi.Importer
}
.....

After that you import the package where you chose to save the file and use it as you normally would :)

johan-lejdung avatar Jun 27 '23 21:06 johan-lejdung

how to use your library. can you give an example? @johan-lejdung

cristian-sima avatar May 29 '24 17:05 cristian-sima

after doing the steps you've provided, it gives me blank pages

cristian-sima avatar May 29 '24 18:05 cristian-sima

after doing the steps you've provided, it gives me blank pages

Hello, I'm not sure why that happens.

I have the wrapper file in a package then I've use the wrapped file for importing files for a project we had. Here is a gist to the file I used: https://gist.github.com/johan-lejdung/2b0fd62871b6f37acaf45e484ffdc69a

Then just use it as the gofpdi package is supposed to be used. eg:

...
importer := NewImporter()
rs := io.ReadSeeker(bytes.NewReader(attachment.Bytes))
tplID := importer.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
pageSizes := importer.GetPageSizes()
...

Also it seems my PR were merged finally (but no new release was made), so maybe you can use the latest git commit from this repo and get around the need for a wrapper file.

johan-lejdung avatar Jun 03 '24 17:06 johan-lejdung