phpdave11 / gofpdi

Go Free PDF Document Importer
MIT License
119 stars 59 forks source link

Unable to import more than one file #59

Open johan-lejdung opened 1 year ago

johan-lejdung commented 1 year ago

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:

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 commented 1 year ago

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

fcarrero commented 1 year ago

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

johan-lejdung commented 1 year ago

@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 :)

cristian-sima commented 6 months ago

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

cristian-sima commented 6 months ago

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

johan-lejdung commented 6 months ago

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.