├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── README.md ├── composer.json ├── imagick └── policy.xml ├── phpunit.xml ├── src ├── LaravelPdf │ ├── Facades │ │ └── Pdf.php │ ├── LaravelPdfFactory.php │ ├── Pdf.php │ ├── PdfInterface.php │ ├── Providers │ │ └── PdfServiceProvider.php │ └── Wrapper │ │ ├── PdfWrapper.php │ │ └── PdfWrapperInterface.php ├── config │ └── pdf.php └── mpdf_ttfonts_config.php └── tests ├── PdfTest.php ├── PdfTestCase.php ├── snapshots ├── exposify.pdf └── simple.pdf └── views └── exposify-expose.html /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | We are only able to handle bug reports at this point in time. If you have an idea on how to improve the library, please submit a pull request. 11 | 12 | **Describe the bug** 13 | A clear and concise description of what the bug is. 14 | 15 | **To Reproduce** 16 | Steps to reproduce the behavior: 17 | 1. Use this method '...' 18 | 2. Download PDF '....' 19 | 3. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE 2 | .idea/ 3 | .project/ 4 | nbproject/ 5 | .buildpath/ 6 | .settings/ 7 | *.sublime-* 8 | 9 | # OS 10 | .DS_Store 11 | *.AppleDouble 12 | *.AppleDB 13 | *.AppleDesktop 14 | 15 | # tooling 16 | vendor/ 17 | composer.lock 18 | .phpunit.result.cache -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Stable Version](https://poser.pugx.org/misterspelik/laravel-pdf/v/stable)](https://packagist.org/packages/misterspelik/laravel-pdf) 2 | [![Unstable Version](https://poser.pugx.org/misterspelik/laravel-pdf/v/unstable)](https://packagist.org/packages/misterspelik/laravel-pdf) 3 | [![License](https://poser.pugx.org/misterspelik/laravel-pdf/license)](https://packagist.org/packages/misterspelik/laravel-pdf) 4 | [![Total Downloads](https://poser.pugx.org/misterspelik/laravel-pdf/downloads)](https://packagist.org/packages/misterspelik/laravel-pdf) 5 | [![Monthly Downloads](https://poser.pugx.org/misterspelik/laravel-pdf/d/monthly)](https://packagist.org/packages/misterspelik/laravel-pdf) 6 | [![Daily Downloads](https://poser.pugx.org/misterspelik/laravel-pdf/d/daily)](https://packagist.org/packages/misterspelik/laravel-pdf) 7 | 8 | 9 | # Laravel PDF: mPDF wrapper for Laravel 10 | 11 | > Easily generate PDF documents from HTML right inside of Laravel using this mPDF wrapper. 12 | 13 | ## Supported versions 14 | 15 | Minimum supported version is Laravel 5 16 | 17 | ## Installation 18 | 19 | Require this package in your `composer.json` or install it by running: 20 | 21 | ``` 22 | composer require misterspelik/laravel-pdf 23 | ``` 24 | 25 | > Note: This package supports auto-discovery features of Laravel 5.5+, You only need to manually add the service provider and alias if working on Laravel version lower then 5.5 26 | 27 | To start using Laravel, add the Service Provider and the Facade to your `config/app.php`: 28 | 29 | ```php 30 | 'providers' => [ 31 | // ... 32 | misterspelik\LaravelPdf\Providers\PdfServiceProvider::class 33 | ] 34 | ``` 35 | 36 | ```php 37 | 'aliases' => [ 38 | // ... 39 | 'PDF' => misterspelik\LaravelPdf\Facades\Pdf::class 40 | ] 41 | ``` 42 | 43 | Now, you should publish package's config file to your config directory by using following command: 44 | 45 | ``` 46 | php artisan vendor:publish 47 | ``` 48 | 49 | ## Basic Usage 50 | 51 | To use Laravel PDF add something like this to one of your controllers. You can pass data to a view in `/resources/views`. 52 | 53 | ```php 54 | use PDF; 55 | 56 | function generate_pdf() { 57 | $data = [ 58 | 'foo' => 'bar' 59 | ]; 60 | $pdf = PDF::loadView('pdf.document', $data); 61 | 62 | return $pdf->stream('document.pdf'); 63 | } 64 | ``` 65 | 66 | ## Other methods 67 | 68 | It is also possible to use the following methods on the `pdf` object: 69 | 70 | `output()`: Outputs the PDF as a string. 71 | `save($filename)`: Save the PDF to a file 72 | `download($filename)`: Make the PDF downloadable by the user. 73 | `stream($filename)`: Return a response with the PDF to show in the browser. 74 | 75 | ## Config 76 | 77 | If you have published config file, you can change the default settings in `config/pdf.php` file: 78 | 79 | ```php 80 | return [ 81 | 'format' => 'A4', // See https://mpdf.github.io/paging/page-size-orientation.html 82 | 'author' => 'John Doe', 83 | 'subject' => 'This Document will explain the whole universe.', 84 | 'keywords' => 'PDF, Laravel, Package, Peace', // Separate values with comma 85 | 'creator' => 'Laravel Pdf', 86 | 'display_mode' => 'fullpage', 87 | ]; 88 | ``` 89 | 90 | To override this configuration on a per-file basis use the fourth parameter of the initializing call like this: 91 | 92 | ```php 93 | PDF::loadView('pdf', $data, [], [ 94 | 'format' => 'A5-L' 95 | ])->save($pdfFilePath); 96 | ``` 97 | 98 | You can use a callback with the key 'instanceConfigurator' to access mpdf functions: 99 | ```php 100 | $config = ['instanceConfigurator' => function($mpdf) { 101 | $mpdf->SetImportUse(); 102 | $mpdf->SetDocTemplate(/path/example.pdf, true); 103 | }] 104 | 105 | PDF::loadView('pdf', $data, [], $config)->save($pdfFilePath); 106 | ``` 107 | 108 | ## Headers and Footers 109 | 110 | If you want to have headers and footers that appear on every page, add them to your `` tag like this: 111 | 112 | ```html 113 | 114 | Your Header Content 115 | 116 | 117 | 118 | Your Footer Content 119 | 120 | ``` 121 | 122 | Now you just need to define them with the name attribute in your CSS: 123 | 124 | ```css 125 | @page { 126 | header: page-header; 127 | footer: page-footer; 128 | } 129 | ``` 130 | 131 | Inside of headers and footers `{PAGENO}` can be used to display the page number. 132 | 133 | ## Included Fonts 134 | 135 | By default you can use all the fonts [shipped with mPDF](https://mpdf.github.io/fonts-languages/available-fonts-v6.html). 136 | 137 | ## Custom Fonts 138 | 139 | You can use your own fonts in the generated PDFs. The TTF files have to be located in one folder, e.g. `/resources/fonts/`. Add this to your configuration file (`/config/pdf.php`): 140 | 141 | ```php 142 | return [ 143 | // ... 144 | 'font_path' => base_path('resources/fonts/'), 145 | 'font_data' => [ 146 | 'examplefont' => [ 147 | 'R' => 'ExampleFont-Regular.ttf', // regular font 148 | 'B' => 'ExampleFont-Bold.ttf', // optional: bold font 149 | 'I' => 'ExampleFont-Italic.ttf', // optional: italic font 150 | 'BI' => 'ExampleFont-Bold-Italic.ttf' // optional: bold-italic font 151 | //'useOTL' => 0xFF, // required for complicated langs like Persian, Arabic and Chinese 152 | //'useKashida' => 75, // required for complicated langs like Persian, Arabic and Chinese 153 | ] 154 | // ...add as many as you want. 155 | ] 156 | // ... 157 | ]; 158 | ``` 159 | 160 | *Note*: If you are using `laravel-pdf` for producing PDF documents in a complicated language (like Persian, Arabic or Chinese) you should have `useOTL` and `useKashida` indexes in your custom font definition array. If you do not use these indexes, your characters will be shown dispatched and incorrectly in the produced PDF. 161 | 162 | Now you can use the font in CSS: 163 | 164 | ```css 165 | body { 166 | font-family: 'examplefont', sans-serif; 167 | } 168 | ``` 169 | 170 | ## Custom Styles 171 | You can use your own styles in the generated PDFs. The css file have to be located in one folder, e.g. `/public/css/`. Add this to your configuration file (`/config/pdf.php`): 172 | 173 | ```php 174 | return [ 175 | //... 176 | 'defaultCssFile' => base_path('public/css/pdf.css'), 177 | ]; 178 | ``` 179 | 180 | ## Set Protection 181 | 182 | To set protection, you just call the `SetProtection()` method and pass an array with permissions, an user password and an owner password. 183 | 184 | The passwords are optional. 185 | 186 | There are a fews permissions: `'copy'`, `'print'`, `'modify'`, `'annot-forms'`, `'fill-forms'`, `'extract'`, `'assemble'`, `'print-highres'`. 187 | 188 | ```php 189 | use PDF; 190 | 191 | function generate_pdf() 192 | { 193 | $data = [ 194 | 'foo' => 'bar' 195 | ]; 196 | $pdf = PDF::loadView('pdf.document', $data); 197 | $pdf->SetProtection(['copy', 'print'], '', 'pass'); 198 | 199 | return $pdf->stream('document.pdf'); 200 | } 201 | ``` 202 | 203 | Find more information to `SetProtection()` here: https://mpdf.github.io/reference/mpdf-functions/setprotection.html 204 | 205 | ## PDF Wrapper extension 206 | 207 | This package has own wrapper for the Mpdf\Mpdf class. But it can be also overrided or extended on the project level. 208 | 209 | There is a setting in the config file to use a custom PdfWrapper. 210 | 211 | ```php 212 | return [ 213 | // ... 214 | 'pdfWrapper' => 'misterspelik\LaravelPdf\Wrapper\PdfWrapper', 215 | ]; 216 | ``` 217 | 218 | The only requirement that the wrapper must implement the interface 219 | `misterspelik\LaravelPdf\PdfInterface\PdfWrapperInterface` 220 | 221 | ## Testing 222 | 223 | To use the testing suite, you need some extensions and binaries for your local PHP. On macOS, you can install them like this: 224 | 225 | ``` 226 | brew install imagemagick ghostscript 227 | pecl install imagick 228 | ``` 229 | 230 | ## License 231 | 232 | Laravel PDF is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) 233 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "misterspelik/laravel-pdf", 3 | "description": "Generate PDFs in Laravel with this mPDF wrapper.", 4 | "keywords": ["mpdf", "pdf", "laravel"], 5 | "license": "MIT", 6 | "homepage": "https://github.com/misterspelik/laravel-pdf", 7 | "authors": [ 8 | { 9 | "name": "Yaroslav Krutikov", 10 | "email": "misterspelik@gmail.com", 11 | "homepage": "https://github.com/misterspelik" 12 | } 13 | ], 14 | "require": { 15 | "php": "^7.4 || ^8.0", 16 | "misterspelik/mpdf": "^8.1.8", 17 | "psr/http-message": "^1.1 || ^2.0", 18 | "psr/log": "^1.1.0 || ^2.0.0 || ^3.0.0" 19 | }, 20 | "require-dev": { 21 | "phpunit/phpunit": "^9.6.0", 22 | "orchestra/testbench": "^8.5.0" 23 | }, 24 | "suggest": { 25 | "ext-gd": "Needed to support images creation and conversion", 26 | "ext-imagick": "Allows more advanced work with images", 27 | "ext-mbstring": "Needed in order to work with multi-byte strings" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "misterspelik\\LaravelPdf\\": "src/LaravelPdf" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "misterspelik\\LaravelPdf\\Test\\": "tests/" 37 | } 38 | }, 39 | "scripts": { 40 | "test": "vendor/bin/phpunit --colors=always" 41 | }, 42 | "extra": { 43 | "laravel": { 44 | "providers": [ 45 | "misterspelik\\LaravelPdf\\Providers\\PdfServiceProvider" 46 | ], 47 | "aliases": { 48 | "PDF": "misterspelik\\LaravelPdf\\Facades\\Pdf" 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /imagick/policy.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | src/ 16 | 17 | 18 | 19 | 20 | tests 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/LaravelPdf/Facades/Pdf.php: -------------------------------------------------------------------------------- 1 | getConfigKey(static::PDF_WRAPPER_CONFIG_KEY); 22 | if ($class !== null) { 23 | return new $class; 24 | } 25 | 26 | return new PdfWrapper(); 27 | } 28 | 29 | /** 30 | * @param string $key 31 | * 32 | * @return mixed 33 | */ 34 | protected function getConfigKey(string $key) 35 | { 36 | return Config::get('pdf.' . $key); 37 | } 38 | } -------------------------------------------------------------------------------- /src/LaravelPdf/Pdf.php: -------------------------------------------------------------------------------- 1 | config = $config; 31 | 32 | // @see https://mpdf.github.io/reference/mpdf-functions/construct.html 33 | $mpdf_config = [ 34 | 'mode' => $this->getConfig('mode'), // Mode of the document. 35 | 'format' => $this->getConfig('format'), // Can be specified either as a pre-defined page size, or as an array of width and height in millimetres 36 | 'default_font_size' => $this->getConfig('default_font_size'), // Sets the default document font size in points (pt). 37 | 'default_font' => $this->getConfig('default_font'), // Sets the default font-family for the new document. 38 | 'margin_left' => $this->getConfig('margin_left'), // Set the page margins for the new document. 39 | 'margin_right' => $this->getConfig('margin_right'), // Set the page margins for the new document. 40 | 'margin_top' => $this->getConfig('margin_top'), // Set the page margins for the new document. 41 | 'margin_bottom' => $this->getConfig('margin_bottom'), // Set the page margins for the new document. 42 | 'margin_header' => $this->getConfig('margin_header'), // Set the page margins for the new document. 43 | 'margin_footer' => $this->getConfig('margin_footer'), // Set the page margins for the new document. 44 | 'orientation' => $this->getConfig('orientation'), // This attribute specifies the default page orientation of the new document if format is defined as an array. This value will be ignored if format is a string value. 45 | 'tempDir' => $this->getConfig('tempDir'), // Temporary directory 46 | ]; 47 | 48 | $defaultCssFile = $this->getConfig('defaultCssFile'); // Set Default Style Sheet 49 | if (file_exists($defaultCssFile)) { 50 | $mpdf_config['defaultCssFile'] = $defaultCssFile; 51 | } 52 | 53 | // Handle custom fonts 54 | $mpdf_config = $this->addCustomFontsConfig($mpdf_config); 55 | 56 | $this->mpdf = new Mpdf\Mpdf($mpdf_config); 57 | 58 | // If you want to change your document title, 59 | // please use the tag. 60 | $this->mpdf->SetTitle('Document'); 61 | 62 | $this->mpdf->SetAuthor ( $this->getConfig('author') ); 63 | $this->mpdf->SetCreator ( $this->getConfig('creator') ); 64 | $this->mpdf->SetSubject ( $this->getConfig('subject') ); 65 | $this->mpdf->SetKeywords ( $this->getConfig('keywords') ); 66 | $this->mpdf->SetDisplayMode ( $this->getConfig('display_mode') ); 67 | 68 | if (!empty($this->getConfig('pdf_a'))) { 69 | $this->mpdf->PDFA = $this->getConfig('pdf_a'); // Set the flag whether you want to use the pdfA-1b format 70 | $this->mpdf->PDFAauto = $this->getConfig('pdf_a_auto'); // Overrides warnings making changes when possible to force PDFA1-b compliance; 71 | } 72 | 73 | if (!empty($this->getConfig('icc_profile_path'))) { 74 | $this->mpdf->ICCProfile = $this->getConfig('icc_profile_path'); // Specify ICC colour profile 75 | } 76 | 77 | if (isset($this->config['instanceConfigurator']) && is_callable(($this->config['instanceConfigurator']))) { 78 | $this->config['instanceConfigurator']($this->mpdf); 79 | } 80 | 81 | $this->mpdf->WriteHTML($html); 82 | } 83 | 84 | /** 85 | * @param string $key 86 | * 87 | * @return mixed 88 | */ 89 | protected function getConfig(string $key) 90 | { 91 | if (isset($this->config[$key])) { 92 | return $this->config[$key]; 93 | } 94 | 95 | return Config::get('pdf.' . $key); 96 | } 97 | 98 | /** 99 | * @param array $mpdfConfig 100 | * 101 | * @return array 102 | */ 103 | protected function addCustomFontsConfig(array $mpdfConfig): array 104 | { 105 | if (!Config::has('pdf.font_path') || !Config::has('pdf.font_data')) { 106 | return $mpdfConfig; 107 | } 108 | 109 | // Get default font configuration 110 | $fontDirs = (new Mpdf\Config\ConfigVariables())->getDefaults()['fontDir']; 111 | $fontData = (new Mpdf\Config\FontVariables())->getDefaults()['fontdata']; 112 | 113 | // Merge default with custom configuration 114 | $mpdfConfig['fontDir'] = array_merge($fontDirs, [Config::get('pdf.font_path')]); 115 | $mpdfConfig['fontdata'] = array_merge($fontData, Config::get('pdf.font_data')); 116 | 117 | return $mpdfConfig; 118 | } 119 | 120 | /** 121 | * Encrypts and sets the PDF document permissions 122 | * 123 | * @param array $permission Permissons e.g.: ['copy', 'print'] 124 | * @param string $userPassword User password 125 | * @param string $ownerPassword Owner password 126 | * 127 | * @return mixed 128 | */ 129 | public function setProtection(array $permission, string $userPassword = '', string $ownerPassword = '') 130 | { 131 | if (func_get_args()[2] === NULL) { 132 | $ownerPassword = bin2hex(openssl_random_pseudo_bytes(8)); 133 | }; 134 | 135 | return $this->mpdf->SetProtection( 136 | $permission, 137 | $userPassword, 138 | $ownerPassword 139 | ); 140 | } 141 | 142 | /** 143 | * Output the PDF as a string. 144 | * 145 | * @return string The rendered PDF as string 146 | */ 147 | public function output() 148 | { 149 | return $this->mpdf->Output('', Destination::STRING_RETURN); 150 | } 151 | 152 | /** 153 | * Save the PDF to a file 154 | * 155 | * @param $filename 156 | * 157 | * @return void 158 | */ 159 | public function save(string $filename) 160 | { 161 | return $this->mpdf->Output($filename, Destination::FILE); 162 | } 163 | 164 | /** 165 | * Make the PDF downloadable by the user 166 | * 167 | * @param string $filename 168 | * 169 | * @return void 170 | */ 171 | public function download(string $filename = 'document.pdf') 172 | { 173 | return $this->mpdf->Output($filename, Destination::DOWNLOAD); 174 | } 175 | 176 | /** 177 | * Return a response with the PDF to show in the browser 178 | * 179 | * @param string $filename 180 | * 181 | * @return void 182 | */ 183 | public function stream(string $filename = 'document.pdf') 184 | { 185 | return $this->mpdf->Output($filename, Destination::INLINE); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/LaravelPdf/PdfInterface.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace misterspelik\LaravelPdf; 4 | 5 | interface PdfInterface 6 | { 7 | /** 8 | * Encrypts and sets the PDF document permissions 9 | * 10 | * @param array $permission Permissons e.g.: ['copy', 'print'] 11 | * @param string $userPassword User password 12 | * @param string $ownerPassword Owner password 13 | * 14 | * @return mixed 15 | */ 16 | public function setProtection(array $permission, string $userPassword = '', string $ownerPassword = ''); 17 | 18 | /** 19 | * Output the PDF as a string. 20 | * 21 | * @return string The rendered PDF as string 22 | */ 23 | public function output(); 24 | 25 | /** 26 | * Save the PDF to a file 27 | * 28 | * @param mixed 29 | * 30 | * @return void 31 | */ 32 | public function save(string $filename); 33 | 34 | /** 35 | * Make the PDF downloadable by the user 36 | * 37 | * @param string $filename 38 | * 39 | * @return void 40 | */ 41 | public function download(string $filename); 42 | 43 | /** 44 | * Return a response with the PDF to show in the browser 45 | * 46 | * @param string $filename 47 | * 48 | * @return void 49 | */ 50 | public function stream(string $filename); 51 | } -------------------------------------------------------------------------------- /src/LaravelPdf/Providers/PdfServiceProvider.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace misterspelik\LaravelPdf\Providers; 4 | 5 | use Illuminate\Support\ServiceProvider; 6 | use misterspelik\LaravelPdf\LaravelPdfFactory; 7 | use misterspelik\LaravelPdf\Wrapper\PdfWrapperInterface; 8 | 9 | class PdfServiceProvider extends ServiceProvider 10 | { 11 | /** 12 | * Indicates if loading of the provider is deferred. 13 | * 14 | * @var bool 15 | */ 16 | protected $defer = false; 17 | 18 | /** 19 | * @var \misterspelik\LaravelPdf\LaravelPdfFactory|null 20 | */ 21 | protected $factory = null; 22 | 23 | /** 24 | * Create a new service provider instance. 25 | * 26 | * @param \Illuminate\Contracts\Foundation\Application $app 27 | * 28 | * @return void 29 | */ 30 | public function __construct($app) 31 | { 32 | $this->app = $app; 33 | $this->factory = new LaravelPdfFactory(); 34 | } 35 | 36 | /** 37 | * Bootstrap the application service 38 | * 39 | * @return void 40 | */ 41 | public function boot() 42 | { 43 | $this->publishes([ 44 | __DIR__ . '/../../config/pdf.php' => config_path('pdf.php'), 45 | ]); 46 | } 47 | 48 | /** 49 | * Register the service provider. 50 | * 51 | * @return void 52 | */ 53 | public function register() 54 | { 55 | $this->mergeConfigFrom( 56 | __DIR__ . '/../../config/pdf.php', 'pdf' 57 | ); 58 | 59 | $this->app->bind('mpdf.wrapper', function ($app) { 60 | return $this->getPdfWrapper(); 61 | }); 62 | } 63 | 64 | /** 65 | * Get the services provided by the provider. 66 | * 67 | * @return array 68 | */ 69 | public function provides() 70 | { 71 | return [ 72 | 'mpdf.pdf' 73 | ]; 74 | } 75 | 76 | /** 77 | * @return \misterspelik\LaravelPdf\Wrapper\PdfWrapperInterface 78 | */ 79 | protected function getPdfWrapper(): PdfWrapperInterface 80 | { 81 | return $this->factory->createPdfWrapper(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/LaravelPdf/Wrapper/PdfWrapper.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace misterspelik\LaravelPdf\Wrapper; 4 | 5 | use File; 6 | use misterspelik\LaravelPdf\Pdf; 7 | use misterspelik\LaravelPdf\PdfInterface; 8 | use View; 9 | 10 | class PdfWrapper implements PdfWrapperInterface 11 | { 12 | /** 13 | * Loads a HTML string 14 | * 15 | * @param string $html 16 | * @param array $config 17 | * 18 | * @return \misterspelik\LaravelPdf\PdfInterface 19 | */ 20 | public function loadHTML(string $html, array $config = []): PdfInterface 21 | { 22 | return new Pdf($html, $config); 23 | } 24 | 25 | /** 26 | * Loads a HTML file 27 | * 28 | * @param string $file 29 | * @param array $config 30 | * 31 | * @return \misterspelik\LaravelPdf\PdfInterface 32 | */ 33 | public function loadFile(string $file, array $config = []): PdfInterface 34 | { 35 | return new Pdf(File::get($file), $config); 36 | } 37 | 38 | /** 39 | * Loads a View and convert to HTML 40 | * 41 | * @param string $view 42 | * @param array $data 43 | * @param array $mergeData 44 | * @param array $config 45 | * 46 | * @return \misterspelik\LaravelPdf\PdfInterface 47 | */ 48 | public function loadView(string $view, array $data = [], array $mergeData = [], array $config = []): PdfInterface 49 | { 50 | return new Pdf( 51 | View::make($view, $data, $mergeData)->render(), 52 | $config 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/LaravelPdf/Wrapper/PdfWrapperInterface.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace misterspelik\LaravelPdf\Wrapper; 4 | 5 | use misterspelik\LaravelPdf\PdfInterface; 6 | 7 | interface PdfWrapperInterface 8 | { 9 | /** 10 | * Loads a HTML string 11 | * 12 | * @param string $html 13 | * @return \misterspelik\LaravelPdf\PdfInterface 14 | */ 15 | public function loadHTML(string $html, array $config = []): PdfInterface; 16 | 17 | /** 18 | * Loads a HTML file 19 | * 20 | * @param string $file 21 | * @param array $config 22 | * 23 | * @return \misterspelik\LaravelPdf\PdfInterface 24 | */ 25 | public function loadFile(string $file, array $config = []): PdfInterface; 26 | 27 | /** 28 | * Loads a View and convert to HTML 29 | * 30 | * @param string $view 31 | * @param array $data 32 | * @param array $mergeData 33 | * @param array $config 34 | * 35 | * @return \misterspelik\LaravelPdf\PdfInterface 36 | */ 37 | public function loadView(string $view, array $data = [], array $mergeData = [], array $config = []): PdfInterface; 38 | } -------------------------------------------------------------------------------- /src/config/pdf.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | return [ 4 | 'mode' => 'utf-8', 5 | 'format' => 'A4', 6 | 'author' => '', 7 | 'subject' => '', 8 | 'keywords' => '', 9 | 'creator' => 'Laravel Pdf', 10 | 'display_mode' => 'fullpage', 11 | 'tempDir' => base_path('../temp/'), 12 | 'pdf_a' => false, 13 | 'pdf_a_auto' => false, 14 | 'icc_profile_path' => '', 15 | 'defaultCssFile' => false, 16 | 'pdfWrapper' => 'misterspelik\LaravelPdf\Wrapper\PdfWrapper', 17 | ]; 18 | -------------------------------------------------------------------------------- /src/mpdf_ttfonts_config.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | use Illuminate\Support\Facades\Config; 4 | 5 | define('_MPDF_SYSTEM_TTFONTS', Config::get('pdf.custom_font_path')); 6 | 7 | $this->fontdata = array_merge($this->fontdata, Config::get('pdf.custom_font_data')); 8 | -------------------------------------------------------------------------------- /tests/PdfTest.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace misterspelik\LaravelPdf\Test; 4 | 5 | use PDF; 6 | use Imagick; 7 | 8 | class PdfTest extends PdfTestCase 9 | { 10 | /** 11 | * @return void 12 | */ 13 | public function testSimplePdfIsCorrect() 14 | { 15 | $pdf = PDF::loadHTML('<p>This gets tested!</p>'); 16 | 17 | $this->compareToSnapshot('simple', $pdf->output()); 18 | } 19 | 20 | /** 21 | * @return void 22 | */ 23 | public function testExposifyPdfExposeIsCorrect() 24 | { 25 | $pdf = PDF::loadFile('tests/views/exposify-expose.html'); 26 | 27 | $this->compareToSnapshot('exposify', $pdf->output()); 28 | } 29 | 30 | /** 31 | * @param string $snapshotId 32 | * @param mixed $data 33 | * 34 | * @return void 35 | */ 36 | protected function compareToSnapshot(string $snapshotId, $data): void 37 | { 38 | $snapshotFile = "tests/snapshots/{$snapshotId}.pdf"; 39 | 40 | // create snapshot if it doesn't exist 41 | if (!file_exists($snapshotFile)) { 42 | file_put_contents($snapshotFile, $data); 43 | } 44 | 45 | $snapshot = file_get_contents($snapshotFile); 46 | $this->assertPdfsLookTheSame($snapshot, $data); 47 | } 48 | 49 | /** 50 | * @param mixed $pdf1 51 | * @param mixed $pdf2 52 | * 53 | * @return void 54 | * 55 | * @throws \ImagickException 56 | */ 57 | protected function assertPdfsLookTheSame($pdf1, $pdf2): void 58 | { 59 | $assertedImagick = new Imagick(); 60 | $assertedImagick->readImageBlob($pdf1); 61 | $assertedImagick->resetIterator(); 62 | $assertedImagick = $assertedImagick->appendImages(true); 63 | 64 | $testImagick = new Imagick(); 65 | $testImagick->readImageBlob($pdf2); 66 | $testImagick->resetIterator(); 67 | $testImagick = $testImagick->appendImages(true); 68 | 69 | $diff = $assertedImagick->compareImages($testImagick, 1); 70 | $pdfsLookTheSame = 0.0 == $diff[1]; 71 | 72 | self::assertTrue($pdfsLookTheSame, 'Failed asserting that PDFs look the same.'); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/PdfTestCase.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace misterspelik\LaravelPdf\Test; 4 | 5 | use misterspelik\LaravelPdf\Facades\Pdf; 6 | use misterspelik\LaravelPdf\Providers\PdfServiceProvider; 7 | use Orchestra\Testbench\TestCase; 8 | 9 | class PdfTestCase extends TestCase 10 | { 11 | /** 12 | * Load package service provider 13 | * @param \Illuminate\Foundation\Application $app 14 | * @return lasselehtinen\MyPackage\MyPackageServiceProvider 15 | */ 16 | protected function getPackageProviders($app): array 17 | { 18 | return [ 19 | PdfServiceProvider::class, 20 | ]; 21 | } 22 | 23 | /** 24 | * Load package alias 25 | * @param \Illuminate\Foundation\Application $app 26 | * @return array 27 | */ 28 | protected function getPackageAliases($app): array 29 | { 30 | return [ 31 | 'PDF' => Pdf::class, 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/snapshots/exposify.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misterspelik/laravel-pdf/5f92d858f1190dd8755f4c72d36b67b8ed8b861b/tests/snapshots/exposify.pdf -------------------------------------------------------------------------------- /tests/snapshots/simple.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misterspelik/laravel-pdf/5f92d858f1190dd8755f4c72d36b67b8ed8b861b/tests/snapshots/simple.pdf -------------------------------------------------------------------------------- /tests/views/exposify-expose.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html> 3 | <head> 4 | <title>Parkstraße 5 | 174 | 175 | 176 | 193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |

Details

202 | 203 | 204 | 212 | 220 | 221 |
205 | 206 | 207 | 208 | 209 | 210 |
Typ:Wohnung zur Miete
211 |
213 | 214 | 215 | 216 | 217 | 218 |
Nummer:#5865
219 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |

Niklas

234 |
235 | test@gmail.com 236 |
237 |
238 | 1234 239 |
240 |
241 |
242 |
243 |
244 | 245 | 246 | --------------------------------------------------------------------------------