{"id":22425210,"url":"https://github.com/2lenet/pdfgeneratorbundle","last_synced_at":"2025-06-27T18:38:10.712Z","repository":{"id":34159476,"uuid":"149089071","full_name":"2lenet/PdfGeneratorBundle","owner":"2lenet","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-07T12:18:16.000Z","size":390,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-07T18:46:26.924Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/2lenet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-17T07:54:48.000Z","updated_at":"2024-06-05T10:16:19.000Z","dependencies_parsed_at":"2023-02-16T08:50:22.481Z","dependency_job_id":"f2871d2a-804d-413c-820b-9e17651e25ba","html_url":"https://github.com/2lenet/PdfGeneratorBundle","commit_stats":{"total_commits":126,"total_committers":15,"mean_commits":8.4,"dds":0.7222222222222222,"last_synced_commit":"9787f64618a254ed3a6a2fb44ea038eab5071a38"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/2lenet/PdfGeneratorBundle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2lenet%2FPdfGeneratorBundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2lenet%2FPdfGeneratorBundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2lenet%2FPdfGeneratorBundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2lenet%2FPdfGeneratorBundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/2lenet","download_url":"https://codeload.github.com/2lenet/PdfGeneratorBundle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2lenet%2FPdfGeneratorBundle/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262313818,"owners_count":23292210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-05T19:13:30.479Z","updated_at":"2025-06-27T18:38:10.684Z","avatar_url":"https://github.com/2lenet.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PdfGeneratorBundle\n\n## Installation\n\n`composer require 2lenet/pdf-generator-bundle`\n\nRequire: unoserver (for word_to_pdf)\n\n```docker-compose\n    unoserver:\n        image: registry.2le.net/2le/2le:unoserver\n```\n\n## Configuration\n\nconfig (with default value):\n\n```yaml\nlle_pdf_generator:\n  path: \"data/pdfmodel\"\n  default_generator: \"word_to_pdf\"\n  class: 'Lle\\PdfGeneratorBundle\\Entity\\PdfModel'\n```\n\nadd routing (for show the ressource\nuse ```\u003ca href=\"{{ path('lle_pdf_generator_show_ressource', {'id': item.id}) }}\"\u003e```)\n\n```yaml\nlle_pdf_generator:\n    resource: \"@LlePdfGeneratorBundle/Resources/config/routes.yaml\"\n    prefix: /\n```\n\nif you create an model without type and with ressource is mydoc.doc the generator will create an pdf based on\ndata/pdfmodel/mydoc.doc with word_to_pdf generator.\n\n## Configure your tags\n\nYou can easily list the tags used in your models.\n\nTo do this, simply declare the route to the page where the tags will be listed. The name of the route is \"\nlle_pdf_generator_admin_balise\".\n\nExample in Crudit:\n\n```php\n\npublic function getListActions(): array\n    {\n        $actions = parent::getListActions();\n\n        array_unshift($actions, ListAction::new(\n            \"action.balise\",\n            Path::new('lle_pdf_generator_admin_balise'),\n            Icon::new(\"bookmark\")\n        ));\n\n        return $actions;\n    }\n\n```\n\nIf you use several document templates linked to different modules, you can declare your annotations in the\npdf_generator.yaml\nof your project:\n\n```yaml\nlle_pdf_generator:\n  path: \"data/pdfmodel\"\n  default_generator: \"word_to_pdf\"\n  data_models:\n    - facture\n    - commande\n```\n\nTo complete the list of tags, use Symfony annotations declared in your pdf_generator.yaml file. For example:\n\n```php\n\u003c?php\n\nnamespace App\\Entity\n\nuse Symfony\\Component\\Serializer\\Annotation\\Groups;\n\nclass Commande\n{\n    /**\n     * @Groups({\"commande\"})\n     */\n    private $type;\n}\n```\n\nIf you only have on template or one module using several templates, you do not have to declare \"data_models\" in the\npdf_generator.yaml\nfile. By default, the Symfony annotation will be \"**pdfgenerator**\". In your entity, you will then have:\n\n```php\n\u003c?php\n\nnamespace App\\Entity\n\nuse Symfony\\Component\\Serializer\\Annotation\\Groups;\n\nclass Commande\n{\n    /**\n     * @Groups({\"pdfgenerator\"})\n     */\n    private $type;\n}\n```\n\n## Use it\n\nYou can use the PDFgenerator with bdd or directly in code\n\n```php\n\u003c?php\n/**\n * @Route(\"/pdf\")\n */\npublic function pdf(PdfGenerator $generator, UserRepository $userRepository)\n{\n    $data = [];\n    foreach($userRepository-\u003efindAll() as $user){\n        $data[] = ['name' =\u003e $user-\u003egetName()];\n    }\n    //create an response by Bdd\n    return $generator-\u003egenerateResponse('MYMODELCODE', $data);\n    //or\n    //create an PdfMerger by Bdd\n    $generator-\u003egenerate('MYMODELCODE', $data)-\u003emerge('pdf.pdf','F');\n    //or\n    //create an PdfMerger by ressource\n    return $generator-\u003egenerateByRessourceResponse(TcpdfGenerator::getName(), MyTcpdfClass::class, $data);\n    //or\n    //create an response by ressource\n    $generator-\u003egenerateByRessource(TcpdfGenerator::getName(), MyTcpdfClass::class, $data)-\u003emerge('pdf.pdf','F');\n}\n```\n\nYou can create an instance of TcpdfFpdi (Tcpdf and Fpdi) with the PdfMerger\n\n```php\n\u003c?php\n$pdfMerger = $generator-\u003egenerate('MYMODELCODE', $data)-\u003emerge('pdf.pdf','F');\n$pdf = $pdfMerger-\u003etoTcpdfFpdi();\n$pdf-\u003eaddPage('P');\n$pdf-\u003ewriteHTML('Hello', true, 0, true, 0);\n$pdf-\u003eOutput('file.pdf', 'F');\nreturn new ResponseBinaryFile('file.pdf');\n```\n\n## Use with your entity:\n\nchange config \"class\" of pdf generator \"App/Entity/MyModelPdf\"\n\n```php\n\n\u003c?php\n\nnamespace App\\Entity;\n\nuse Vich\\UploaderBundle\\Mapping\\Annotation as Vich;\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Lle\\PdfGeneratorBundle\\Entity as PDF;\n\n/**\n *\n * @ORM\\Table(name=\"lle_pdf_model\", indexes={@ORM\\Index(name=\"code_idx\", columns={\"code\"})})\n * @ORM\\Entity\n * @Vich\\Uploadable\n */\nclass MyModelPdf implements PDF\\PdfModelInterface\n{\n    use PDF\\PdfModelTrait;\n}\n```\n\n## Use with bdd\n\nThe model is a PdfModel with\n\na code, a ressource, a libelle, a type and a description\n\nyou can create a model with\n\n```\nphp bin/console lle:pdf-generator:create-model\n```\n\n!! Warning if you use your own class and this class has other field with constraint the command not work. !!\n\n## Create your own type\n\nyou can create several type of pdf (already exist tcpdf and word_to_pdf)\n\n- word_to_pdf (the ressource is an path of .docx format Microsoft Word XML)\n- tcpdf (the ressource is an class which extend Lle\\PdfGeneratorBundle\\Lib\\Pdf (Tcpdf and Fpdi))\n\nYou can create your own type with an class which extend Lle\\PdfGeneratorBundle\\Generator\\AbstractPdfGenerator\n\nAbstractPdfGenerator implements Lle\\PdfGeneratorBundle\\Generator\\PdfGeneratorInterface (autotagged lle.pdf.generator)\n\n```php\n    public static function getName():string; //name of type\n    public function generate(string $source, iterable $params, string $savePath):void; //generate the pdf with the ressource $source and parameters $params in a tmp file $savePath\n    public function getRessource(string $pdfPath, string $modelRessource): string; //calcule the ressource with pdfPath or not (the ressource can be an class name for exemple)\n```\n\nan exemple is:\n\n```php\n\u003c?php\nclass TcpdfGenerator extends AbstractPdfGenerator\n{\n\n    private $pdfPath;\n    \n    public function generate(string $source, iterable $params, string $savePath):void{\n        $reflex = new \\ReflectionClass($source);\n        $pdf = $reflex-\u003enewInstance();\n        if ($pdf instanceof Pdf) {\n            $pdf-\u003esetRootPath($this-\u003epdfPath);\n            $pdf-\u003esetData($params['vars']);\n            $pdf-\u003einitiate();\n            $pdf-\u003egenerate();\n            $pdf-\u003esetTitle($pdf-\u003etitle());\n        } else {\n            throw new \\Exception('PDF GENERATOR ERROR: ressource '.$source.' n\\'est pas une class PDF');\n        }\n        $pdf-\u003eoutput($savePath, 'F');\n    }\n\n    //$pdfPath is in config lle_pdf_generator.path (default:data/pdfmodel)\n    public function getRessource(string $pdfPath, string $modelRessource): string{\n        $this-\u003epdfPath = $pdfPath;\n        return $modelRessource;\n    }\n\n    public static function getName(): string{\n        return 'tcpdf';\n    }\n}\n```\n\n## Use the type tcpdf\n\nAn exemple for tcpdf:\n\n```php\n\u003c?php\n\nnamespace App\\Service\\Pdf;\n\nuse Lle\\PdfGeneratorBundle\\Lib\\Pdf;\n\nclass MyTcpdfClass extends Pdf\n{\n\n    //$this-\u003erootPath is in config lle_pdf_generator.path (default:data/pdfmodel)\n    public function init()\n    {\n        $this-\u003esetSourceFile($this-\u003erootPath . 'background.pdf');\n    }\n    \n    public function myColors()\n    {\n        return ['blanc' =\u003e 'FFFFFF','default'=\u003e '000000', 'red' =\u003e 'FF0000'];\n    }\n\n    //the fonts is in $this-\u003erootPath.'/fonts'\n    public function myFonts()\n    {\n        return ['titre' =\u003e ['size'=\u003e12,'color'=\u003e'noir','family'=\u003e'courier', 'style'=\u003e'BU']];\n    }\n\n    public function generate()\n    {\n        $this-\u003eAddPage('P');\n        $this-\u003eshowGrid(5); //is an debug function which show an gride by 5px\n        $this-\u003echangeFont('titre');\n        $this-\u003ew(10,10,'Hello \u003cb\u003e'. $this-\u003edata['name'] .'\u003c/b\u003e');\n    }\n\n    public function footer()\n    {\n    }\n}\n```\n\n```php\n\u003c?php\n/**\n * @Route(\"/pdf\")\n */\npublic function pdf(PdfGenerator $generator, UserRepository $userRepository)\n{\n    $data = [];\n    foreach($userRepository-\u003efindAll() as $user){\n        $data[] = ['name' =\u003e $user-\u003egetName()];\n    }\n    return $generator-\u003egenerateByRessourceResponse(TcpdfGenerator::getName(), MyTcpdfClass::class, $data);\n}\n```\n\nYou can create an pdf model in bdd with ressource \"App\\Service\\Pdf\\MyTcpdfClass\" and code MYTCPDF type \"tcpdf\"\n\n```php\n\u003c?php\n/**\n * @Route(\"/pdf\")\n */\npublic function pdf(PdfGenerator $generator, UserRepository $userRepository)\n{\n    $data = [];\n    foreach($userRepository-\u003efindAll() as $user){\n        $data[] = ['name' =\u003e $user-\u003egetName()];\n    }\n    return $generator-\u003egenerateResponse('MYTCPDF', $data);\n}\n```\n\n## use the word_to_pdf (format Microsoft Word XML)\n\nCreate a .docx file /data/pdfmodel/test.docx with Hello ${name}\n\n```php\n\u003c?php\n/**\n * @Route(\"/pdf\")\n */\npublic function pdf(PdfGenerator $generator, UserRepository $userRepository)\n{\n    $data = [];\n    foreach($userRepository-\u003efindAll() as $user){\n        $data[] = ['name' =\u003e $user-\u003egetName()];\n    }\n    return $generator-\u003egenerateByRessourceResponse(WordToPdfGenerator::getName(), 'test.docx', $data);\n}\n\n\n```\n\nYou can create an pdf model in bdd with ressource \"test.docx\" and code MYDOC type \"word_to_pdf\"\n\n```php\n\u003c?php\n/**\n * @Route(\"/pdf\")\n */\npublic function pdf(PdfGenerator $generator, UserRepository $userRepository)\n{\n    $data = [];\n    foreach($userRepository-\u003efindAll() as $user){\n        $data[] = ['name' =\u003e $user-\u003egetName()];\n    }\n    return $generator-\u003egenerateResponse('MYDOC', $data);\n}\n```\n\nyou can use variables ${@img[logo]:100x200} or ${@img[logo]} for create images. (regex is #^@img\\[(\\w+)\\](:(\\d+)x(\n\\d+))?$#)\n\n```php\n$generator-\u003egenerateResponse('MYDOC', [['logo'=\u003e 'logo.png']]);\n```\n\nsearch to {{lle_pdf_generator.path}}/logo.png so default is data/pdfmodel/logo.png\n\n```php\n$generator-\u003egenerateResponse('MYDOC', [['logo'=\u003e '/logo.png']]);\n```\n\nsearch to /logo.png\n\nhttps://phpword.readthedocs.io/en/latest/templates-processing.html\n\n##Sign pdf\n\nUse the Lle\\PdfGeneratorBundle\\Lib\\Signature class you can sign an pdf response or an PdfMerge\n\n### Cretae the signature\n\n```\nopenssl req -x509 -nodes -days 365000 -newkey rsa:1024 -keyout tcpdf.crt -out tcpdf.crt\nopenssl pkcs12 -export -in tcpdf.crt -out tcpdf.p12\n```\n\n```php\n\u003c?php\n$password = '***';\n$info = [\n    'Name' =\u003e 'name',\n    'Location' =\u003e 'location',\n    'Reason' =\u003e 'reason',\n    'ContactInfo' =\u003e 'url',\n];\n$signature = new Signature($generator-\u003egetPath().'cert/tcpdf.crt', $password, $info);\n```\n\nYou can add an draw with signature\n\n```php\n\u003c?php\n/*...*/\n$picture = 'signature.png';\n$signature = new Signature($generator-\u003egetPath().'cert/tcpdf.crt', $password, $info, $pictur);\n//or\n$pos = [\n    'w' =\u003e 40, //width default 40\n    'h' =\u003e 20, //heght default 20\n    'x' =\u003e 10, //x default pageWidth - w\n    'y' =\u003e 10, //y default pageHeight - (h*2+5)\n    'p' =\u003e 1 //page default last page\n];\n$signature = new Signature($generator-\u003egetPath().'cert/tcpdf.crt', $password, $info, $pictur, $pos);\n```\n\nYou can also add segment or points for create the signature picture\n\n```php\n\u003c?php\n$signature = new Signature($certif, $password, $info);\n\n$signature-\u003esetSegments([[$x1,$y1],[$x2,$y2]], $pos);\n//or\n$signature-\u003esetPoints([$x1,$y1,$x2,$y2], $pos);\n//or\n$signature-\u003esetImage('signe.png', $pos);\n\n$signature-\u003esetPosition($pos); // you can use it also\n```\n\n### Pdf response\n\n```php\n\u003c?php\nreturn $generator-\u003egenerateByRessourceResponse(WordToPdfGenerator::getName(), 'test.docx', $data, [$signature]);\n//or\nreturn $generator-\u003egenerateResponse('MYMODELCODE', $data, [$signature]);\n```\n\n### Pdf Merger\n\nThe pdfMerge is the class of instance return by generator\n\n```php\n\u003c?php\n$pdfMerger = $generator-\u003egenerateByRessource(WordToPdfGenerator::getName(), 'test.docx', $data);\n//or\n$pdfMerger = $generator-\u003egenerate('MYMODELCODE', $data);\n$pdf = $generator-\u003esignes($pdfMerger, [$signature]); //return an TcpdfFpdi (signe($pdfMerger, $signature) exist also)\n$pdf-\u003eOutput('My pdf', 'D'); // return a signed pdf\n$pdfMerger-\u003emerge('My pdf', 'D'); // return a unsigned pdf\n```\n\nYou can't signed a pdfMerger you have to pass by TcpdfFpdi. An PdfMerger instance can never be signed\n\nYou can continue to sign an TcpdfFpdi with $generator-\u003esigneTcpdfFpdi($pdf, $signature)\n\nYou can also use directly the signature instance for sign a Pdfmerger or TcpdfFpdi\n\n```php\n\u003c?php\n$pdfMerger = $generator-\u003egenerate('MYMODELCODE', $data);\n$signature-\u003esigne($pdfMerger)-\u003eOutput('My pdf', 'D');\n```\n\nor\n\n```php\n\u003c?php\n$pdfMerger = $generator-\u003egenerate('MYMODELCODE', $data);\n$pdf = $pdfMerger-\u003etoTcpdfFpdi();\n$pdf = $signature-\u003esigneTcpdfFpdi($pdf);\n$pdf = $signature2-\u003esigneTcpdfFpdi($pdf);\n$pdf-\u003eOutput('My pdf', 'D');\n```\n\nYou can't use several sign with PdfMerger\n\n## ieterable data\n\ncreate a .docx file and create 2 table (1 line , 3 cells)\n\n- first table cells 1 write ${eleves.nom} , cells 2 write ${eleves.etablissement.nom}, cells 3 write\n  ${@img[eleves.logo]}\n- second table cells 1 write ${users.[nom]}, cells 2 write ${users.[adresse][rue]}, cells 3 write ${@img[users.[logo]]}\n\nsave it with myiterable.docx\nuse the Lle\\PdfGeneratorBundle\\Lib\\PdfIterable class\n\n```php\n\u003c?php\n$data = [\n    'eleves' =\u003e new PdfIterable($this-\u003eem-\u003egetRepository(Eleve::class)-\u003efindAll()),\n    'users' =\u003e new PdfIterable([['nom'=\u003e'saenger','adresse'=\u003e['rue'=\u003e'rue du chat'], 'logo'=\u003e'logo.png'], ['nom'=\u003e'boehler', 'adresse'=\u003e['rue'=\u003e'rue du chien'], 'logo.png']]),            \n];\nreturn $generator-\u003egenerateByRessourceResponse(WordToPdfGenerator::getName(), 'myiterable.docx', $data);\n```\n\nshow it\n\nWarning only the first level of data can to be an PdfIterable, you can't use ${etablissement.eleves}:\n\n```php\n\u003c?php\n$data = [\n    'etablissement' =\u003e $etablissement,\n    'eleves' =\u003e PdfIterable($etablissement-\u003egetEleves())\n];\n```\n\n# Understand the property (word to pdf)\n\nThe property is read with propertyAccesor (Symfony) but the first is beetween two \"[]\": [first].rest\n\n```\nthe vars ${eleve.etablissement.nom} -\u003e $propertyAccess-\u003egetValue($params, '[eleve].etablissement.nom')\nthe vars ${eleve.etablissement[nom]} -\u003e $propertyAccess-\u003egetValue($params, '[eleve].etablissement[nom]')\n```\n\n!!! warning use the same systeme if you create your own type !!!\n\n## Merge several model\n\n```php\n\u003c?php\nreturn $generator-\u003egenerateByRessourceResponse(\n    TcpdfGenerator::getName(), \n    [MyTcpdfClass::class,AnotherTcpdfClass::class], \n    $data);\n```\n\n```php\n\u003c?php\nreturn $generator-\u003egenerateByRessourceResponse(\n    [TcpdfGenerator::getName(),WortdToPdfGenerator::getName()], \n    [MyTcpdfClass::class,'mydoc.docx'], \n    $data);\n```\n\nin bdd:\n\n```sql\nINSERT INTO `lle_pdf_model` (`code`, `path`, `type`) VALUES\n('RELANCE_1ANS', 'mydoc.docx,App\\\\Service\\\\Pdf\\\\LotInvitation', 'word_to_pdf,tcpdf')\n```\n\nThe default type is always the first (here \"word_to_pdf\")\n\nif none type is defined the type is lle_pdf_generator.default_generator config\n\n## Migrate to pdf generator v3\nThere is few breaks in backward compatibility in v3. Here is the steps to migrate :\n- `@LlePdfGeneratorBundle/Resources/routing/routes.yaml` is now in `@LlePdfGeneratorBundle/Resources/config/routes.yaml`\n- The class `Lle\\PdfGeneratorBundle\\Entity\\PdfModelCustomFileTrait` is replaced by `Lle\\PdfGeneratorBundle\\Entity\\PdfModelTrait` and now the trait include the `$file` property\n- The route `lle_pdf_generator_show_ressource` change to `lle_pdf_generator_show_model`\n- The route `lle_pdf_generator_show_pdf` change to `lle_pdf_generator_download_model`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2lenet%2Fpdfgeneratorbundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F2lenet%2Fpdfgeneratorbundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2lenet%2Fpdfgeneratorbundle/lists"}