gofpdi.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. Package gofpdi wraps the gofpdi PDF library to import existing PDFs as templates. See github.com/phpdave11/gofpdi
  3. for further information and examples.
  4. Users should call NewImporter() to obtain their own Importer instance to work with.
  5. To retain backwards compatibility, the package offers a default Importer that may be used via global functions. Note
  6. however that use of the default Importer is not thread safe.
  7. */
  8. package gofpdi
  9. import (
  10. realgofpdi "github.com/phpdave11/gofpdi"
  11. "io"
  12. )
  13. // gofpdiPdf is a partial interface that only implements the functions we need
  14. // from the PDF generator to put the imported PDF templates on the PDF.
  15. type gofpdiPdf interface {
  16. ImportObjects(objs map[string][]byte)
  17. ImportObjPos(objs map[string]map[int]string)
  18. ImportTemplates(tpls map[string]string)
  19. UseImportedTemplate(tplName string, x float64, y float64, w float64, h float64)
  20. SetError(err error)
  21. }
  22. // Importer wraps an Importer from the gofpdi library.
  23. type Importer struct {
  24. fpdi *realgofpdi.Importer
  25. }
  26. // NewImporter creates a new Importer wrapping functionality from the gofpdi library.
  27. func NewImporter() *Importer {
  28. return &Importer{
  29. fpdi: realgofpdi.NewImporter(),
  30. }
  31. }
  32. // ImportPage imports a page of a PDF file with the specified box (/MediaBox,
  33. // /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
  34. // be used with UseImportedTemplate to draw the template onto the page.
  35. func (i *Importer) ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
  36. // Set source file for fpdi
  37. i.fpdi.SetSourceFile(sourceFile)
  38. // return template id
  39. return i.getTemplateID(f, pageno, box)
  40. }
  41. // ImportPageFromStream imports a page of a PDF with the specified box
  42. // (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
  43. // that can be used with UseImportedTemplate to draw the template onto the
  44. // page.
  45. func (i *Importer) ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
  46. // Set source stream for fpdi
  47. i.fpdi.SetSourceStream(rs)
  48. // return template id
  49. return i.getTemplateID(f, pageno, box)
  50. }
  51. func (i *Importer) getTemplateID(f gofpdiPdf, pageno int, box string) int {
  52. // Import page
  53. tpl := i.fpdi.ImportPage(pageno, box)
  54. // Import objects into current pdf document
  55. // Unordered means that the objects will be returned with a sha1 hash instead of an integer
  56. // The objects themselves may have references to other hashes which will be replaced in ImportObjects()
  57. tplObjIDs := i.fpdi.PutFormXobjectsUnordered()
  58. // Set template names and ids (hashes) in gofpdf
  59. f.ImportTemplates(tplObjIDs)
  60. // Get a map[string]string of the imported objects.
  61. // The map keys will be the ID of each object.
  62. imported := i.fpdi.GetImportedObjectsUnordered()
  63. // Import gofpdi objects into gofpdf
  64. f.ImportObjects(imported)
  65. // Get a map[string]map[int]string of the object hashes and their positions within each object,
  66. // to be replaced with object ids (integers).
  67. importedObjPos := i.fpdi.GetImportedObjHashPos()
  68. // Import gofpdi object hashes and their positions into gopdf
  69. f.ImportObjPos(importedObjPos)
  70. return tpl
  71. }
  72. // UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
  73. // template will be scaled to fit based on h. If h is 0, the template will be
  74. // scaled to fit based on w.
  75. func (i *Importer) UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
  76. // Get values from fpdi
  77. tplName, scaleX, scaleY, tX, tY := i.fpdi.UseTemplate(tplid, x, y, w, h)
  78. f.UseImportedTemplate(tplName, scaleX, scaleY, tX, tY)
  79. }
  80. // GetPageSizes returns page dimensions for all pages of the imported pdf.
  81. // Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
  82. // <page number>: page number, note that page numbers start at 1
  83. // <box>: box identifier, e.g. "/MediaBox"
  84. // <dimension>: dimension string, either "w" or "h"
  85. func (i *Importer) GetPageSizes() map[int]map[string]map[string]float64 {
  86. return i.fpdi.GetPageSizes()
  87. }
  88. // Default Importer used by global functions
  89. var fpdi = NewImporter()
  90. // ImportPage imports a page of a PDF file with the specified box (/MediaBox,
  91. // /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
  92. // be used with UseImportedTemplate to draw the template onto the page.
  93. // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
  94. func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
  95. return fpdi.ImportPage(f, sourceFile, pageno, box)
  96. }
  97. // ImportPageFromStream imports a page of a PDF with the specified box
  98. // (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
  99. // that can be used with UseImportedTemplate to draw the template onto the
  100. // page.
  101. // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
  102. func ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
  103. return fpdi.ImportPageFromStream(f, rs, pageno, box)
  104. }
  105. // UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
  106. // template will be scaled to fit based on h. If h is 0, the template will be
  107. // scaled to fit based on w.
  108. // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
  109. func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
  110. fpdi.UseImportedTemplate(f, tplid, x, y, w, h)
  111. }
  112. // GetPageSizes returns page dimensions for all pages of the imported pdf.
  113. // Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
  114. // <page number>: page number, note that page numbers start at 1
  115. // <box>: box identifier, e.g. "/MediaBox"
  116. // <dimension>: dimension string, either "w" or "h"
  117. // Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
  118. func GetPageSizes() map[int]map[string]map[string]float64 {
  119. return fpdi.GetPageSizes()
  120. }