├── .gitignore ├── README.md ├── api.php ├── composer.json ├── composer.lock ├── index.html ├── lib ├── bionic │ └── wkhtmltopdf └── xenial │ └── wkhtmltopdf └── src ├── DHtml2Pdf ├── ApiUtils.php ├── DHtml2Pdf.php └── Exception │ └── WkhtmltopdfDriverNotFoundException.php └── autoload.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .env 3 | .idea/ 4 | .idea/workspace.xml 5 | /**/.DS_Store 6 | */.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # [dhtml2pdf](https://dellos7.github.io/dhtml2pdf/) 3 | 4 | **dhtml2pdf** is a simple, free and very easy to use PHP API that allows you to 5 | see, download or get the binary of the PDF generated from the HTML of an URL. 6 | 7 | It uses the [snappy](https://github.com/knplabs/snappy) image & PDF from URL generation PHP library, 8 | which is based in the awesome webkit-based [wkhtmltopdf and wkhtmltoimage](https://wkhtmltopdf.org/) CLI. 9 | 10 | 11 | Try it out here! :point_right: [https://dhtml2pdf.herokuapp.com/](https://dhtml2pdf.herokuapp.com/) 12 | 13 | > As I'm using the free Heroku containers to host the app, so it sometimes stops working because of the quota limits they have. I've created a second instance of the app (👉[https://dhtml2pdf2.herokuapp.com/](https://dhtml2pdf2.herokuapp.com/)) which you can use, however I recommend you [set up your own private Heroku instance](#Deploy-your-own-server-API) if you plan to frequently use this 14 | 15 | # The API 16 | 17 | Currently, the API is an PHP-based end point which simply 18 | allows you to pass as parameter the URL of the HTML page that you want 19 | to convert to PDF. It's deployed as a [Heroku](https://www.heroku.com/home) 20 | APP so you can use it whenever you want to. 21 | 22 | It's as easy as this: 23 | 24 | ``` 25 | https://dhtml2pdf.herokuapp.com/api.php?url=&result_type= 26 | ``` 27 | 28 | **Params**: 29 | 30 | * `url`. The URL of the site you want to convert to PDF. Example: `url=https://www.github.com` 31 | * `result_type`. The way you want to retrieve the generated PDF. Can be 32 | one of the following: 33 | * `show`. Opens the generated PDF in the browser. 34 | * `download`. Downloads the generated PDF. 35 | * `binary`. Returns the binary content of the generated PDF. 36 | * `file_name`. If you choose `download` in the `result_type` parameter, 37 | this is the name of the file that will be downloaded (you must pass the name) 38 | without the **.pdf** extension. 39 | 40 | **Example**: 41 | 42 | This: 43 | ``` 44 | https://dhtml2pdf.herokuapp.com/api.php?url=https://www.github.com&result_type=show 45 | ``` 46 | 47 | would open the generated PDF from the `https://www.github.com` site in your browser. 48 | 49 | # Examples 50 | 51 | ## HTML 52 | 53 | Anchor to show the PDF in a new browser tab: 54 | ```html 55 | Show PDF 56 | ``` 57 | 58 | Anchor to download the PDF as **my_pdf.pdf**: 59 | ```html 60 | Download PDF 61 | ``` 62 | 63 | > PRO TIP: Show or download current page in PDF 64 | ```html 65 | Show PDF 66 | ``` 67 | 68 | ## jQuery 69 | 70 | Retrieve the binary data of the PDF: 71 | ```javascript 72 | $.ajax({ 73 | type: "GET", 74 | url: "https://dhtml2pdf.herokuapp.com/api.php?url=https://www.github.com&&result_type=binary", 75 | success: function(data){ 76 | //Prints the PDF binary data in the browser console 77 | console.log(data); 78 | }, 79 | error: function(err) { 80 | console.log(err); 81 | } 82 | }); 83 | ``` 84 | 85 | # Deploy your own server API 86 | 87 | If you don't want to depend on a external service as this one, you 88 | can easily clone the repo and deploy it in your own server. I will show 89 | how to deploy it in a [Heroku](https://www.heroku.com/home) server as it's easy and fast to install and free! 90 | 91 | Clone the repo: 92 | 93 | ```shell 94 | git clone https://github.com/Dellos7/dhtml2pdf.git 95 | ``` 96 | 97 | ```shell 98 | cd dhtml2pdf 99 | ``` 100 | 101 | > If you had any troubles following the below instructions, please visit the 102 | Heroku PHP getting started guide at [https://devcenter.heroku.com/articles/getting-started-with-php#set-up](https://devcenter.heroku.com/articles/getting-started-with-php#set-up) 103 | 104 | Sign up in Heroku: [https://signup.heroku.com/](https://signup.heroku.com/) 105 | 106 | Download & install Heroku CLI: [https://devcenter.heroku.com/articles/heroku-cli#download-and-install](https://devcenter.heroku.com/articles/heroku-cli#download-and-install) 107 | 108 | Login in the Heroku CLI: 109 | 110 | ```shell 111 | heroku login 112 | ``` 113 | 114 | Create your Heroku APP: 115 | 116 | ```shell 117 | heroku create 118 | ``` 119 | 120 | (your APP name will be deployed then in https://.herokuapp.com) 121 | 122 | Update & create the composer dependencies: 123 | 124 | ```shell 125 | composer update 126 | ``` 127 | 128 | Remove the current git repository and create a Heroku one: 129 | 130 | ```shell 131 | rm -r .git 132 | git init 133 | git remote add heroku https://git.heroku.com/.git 134 | git add . 135 | git commit -m "first commit" 136 | ``` 137 | 138 | We only need a last command in order to push our APP to heroku, which 139 | will perform the PHP build and deploy the APP! 140 | 141 | ```shell 142 | git push -u heroku master 143 | ``` 144 | 145 | > Working currently on `heroku-16` stack and `heroku-18` stack 146 | 147 | # License 148 | 149 | [GPL 3.0 License](https://choosealicense.com/licenses/gpl-3.0/) -------------------------------------------------------------------------------- /api.php: -------------------------------------------------------------------------------- 1 | convertHtml2PdfFromUrl( $url ); 24 | if( $pdfBinary ) { 25 | ApiUtils::sendResultFromResultType( $resultType, $pdfBinary, $fileName ); 26 | } 27 | else { 28 | throw new Exception( ApiError::PDF_CREATE_ERROR ); 29 | } 30 | } 31 | catch( Exception $e ) { 32 | ApiUtils::error( $e->getMessage() ); 33 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "knplabs/knp-snappy": "^1.2.1" 4 | }, 5 | 6 | "require-dev": { 7 | "heroku/heroku-buildpack-php": "*" 8 | } 9 | 10 | } -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "61ea15218f7e3b906253edc5e4ab5679", 8 | "packages": [ 9 | { 10 | "name": "knplabs/knp-snappy", 11 | "version": "v1.2.1", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/KnpLabs/snappy.git", 15 | "reference": "7bac60fb729147b7ccd8532c07df3f52a4afa8a4" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/KnpLabs/snappy/zipball/7bac60fb729147b7ccd8532c07df3f52a4afa8a4", 20 | "reference": "7bac60fb729147b7ccd8532c07df3f52a4afa8a4", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=7.1", 25 | "psr/log": "^1.0", 26 | "symfony/process": "~3.4||~4.3||~5.0" 27 | }, 28 | "require-dev": { 29 | "phpunit/phpunit": "~7.4" 30 | }, 31 | "suggest": { 32 | "h4cc/wkhtmltoimage-amd64": "Provides wkhtmltoimage-amd64 binary for Linux-compatible machines, use version `~0.12` as dependency", 33 | "h4cc/wkhtmltoimage-i386": "Provides wkhtmltoimage-i386 binary for Linux-compatible machines, use version `~0.12` as dependency", 34 | "h4cc/wkhtmltopdf-amd64": "Provides wkhtmltopdf-amd64 binary for Linux-compatible machines, use version `~0.12` as dependency", 35 | "h4cc/wkhtmltopdf-i386": "Provides wkhtmltopdf-i386 binary for Linux-compatible machines, use version `~0.12` as dependency", 36 | "wemersonjanuario/wkhtmltopdf-windows": "Provides wkhtmltopdf executable for Windows, use version `~0.12` as dependency" 37 | }, 38 | "type": "library", 39 | "extra": { 40 | "branch-alias": { 41 | "dev-master": "1.x-dev" 42 | } 43 | }, 44 | "autoload": { 45 | "psr-4": { 46 | "Knp\\Snappy\\": "src/Knp/Snappy" 47 | } 48 | }, 49 | "notification-url": "https://packagist.org/downloads/", 50 | "license": [ 51 | "MIT" 52 | ], 53 | "authors": [ 54 | { 55 | "name": "KnpLabs Team", 56 | "homepage": "http://knplabs.com" 57 | }, 58 | { 59 | "name": "Symfony Community", 60 | "homepage": "http://github.com/KnpLabs/snappy/contributors" 61 | } 62 | ], 63 | "description": "PHP5 library allowing thumbnail, snapshot or PDF generation from a url or a html page. Wrapper for wkhtmltopdf/wkhtmltoimage.", 64 | "homepage": "http://github.com/KnpLabs/snappy", 65 | "keywords": [ 66 | "knp", 67 | "knplabs", 68 | "pdf", 69 | "snapshot", 70 | "thumbnail", 71 | "wkhtmltopdf" 72 | ], 73 | "time": "2020-01-20T08:30:30+00:00" 74 | }, 75 | { 76 | "name": "psr/log", 77 | "version": "1.1.3", 78 | "source": { 79 | "type": "git", 80 | "url": "https://github.com/php-fig/log.git", 81 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" 82 | }, 83 | "dist": { 84 | "type": "zip", 85 | "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", 86 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", 87 | "shasum": "" 88 | }, 89 | "require": { 90 | "php": ">=5.3.0" 91 | }, 92 | "type": "library", 93 | "extra": { 94 | "branch-alias": { 95 | "dev-master": "1.1.x-dev" 96 | } 97 | }, 98 | "autoload": { 99 | "psr-4": { 100 | "Psr\\Log\\": "Psr/Log/" 101 | } 102 | }, 103 | "notification-url": "https://packagist.org/downloads/", 104 | "license": [ 105 | "MIT" 106 | ], 107 | "authors": [ 108 | { 109 | "name": "PHP-FIG", 110 | "homepage": "http://www.php-fig.org/" 111 | } 112 | ], 113 | "description": "Common interface for logging libraries", 114 | "homepage": "https://github.com/php-fig/log", 115 | "keywords": [ 116 | "log", 117 | "psr", 118 | "psr-3" 119 | ], 120 | "time": "2020-03-23T09:12:05+00:00" 121 | }, 122 | { 123 | "name": "symfony/process", 124 | "version": "v5.0.8", 125 | "source": { 126 | "type": "git", 127 | "url": "https://github.com/symfony/process.git", 128 | "reference": "3179f68dff5bad14d38c4114a1dab98030801fd7" 129 | }, 130 | "dist": { 131 | "type": "zip", 132 | "url": "https://api.github.com/repos/symfony/process/zipball/3179f68dff5bad14d38c4114a1dab98030801fd7", 133 | "reference": "3179f68dff5bad14d38c4114a1dab98030801fd7", 134 | "shasum": "" 135 | }, 136 | "require": { 137 | "php": "^7.2.5" 138 | }, 139 | "type": "library", 140 | "extra": { 141 | "branch-alias": { 142 | "dev-master": "5.0-dev" 143 | } 144 | }, 145 | "autoload": { 146 | "psr-4": { 147 | "Symfony\\Component\\Process\\": "" 148 | }, 149 | "exclude-from-classmap": [ 150 | "/Tests/" 151 | ] 152 | }, 153 | "notification-url": "https://packagist.org/downloads/", 154 | "license": [ 155 | "MIT" 156 | ], 157 | "authors": [ 158 | { 159 | "name": "Fabien Potencier", 160 | "email": "fabien@symfony.com" 161 | }, 162 | { 163 | "name": "Symfony Community", 164 | "homepage": "https://symfony.com/contributors" 165 | } 166 | ], 167 | "description": "Symfony Process Component", 168 | "homepage": "https://symfony.com", 169 | "time": "2020-04-15T15:59:10+00:00" 170 | } 171 | ], 172 | "packages-dev": [ 173 | { 174 | "name": "heroku/heroku-buildpack-php", 175 | "version": "v176", 176 | "source": { 177 | "type": "git", 178 | "url": "https://github.com/heroku/heroku-buildpack-php.git", 179 | "reference": "6c6cc209a95c65f01d4715540459d5d673be19dc" 180 | }, 181 | "dist": { 182 | "type": "zip", 183 | "url": "https://api.github.com/repos/heroku/heroku-buildpack-php/zipball/6c6cc209a95c65f01d4715540459d5d673be19dc", 184 | "reference": "6c6cc209a95c65f01d4715540459d5d673be19dc", 185 | "shasum": "" 186 | }, 187 | "bin": [ 188 | "bin/heroku-hhvm-apache2", 189 | "bin/heroku-hhvm-nginx", 190 | "bin/heroku-php-apache2", 191 | "bin/heroku-php-nginx" 192 | ], 193 | "type": "library", 194 | "notification-url": "https://packagist.org/downloads/", 195 | "license": [ 196 | "MIT" 197 | ], 198 | "authors": [ 199 | { 200 | "name": "David Zuelke", 201 | "email": "dz@heroku.com" 202 | } 203 | ], 204 | "description": "Toolkit for starting a PHP application locally, with or without foreman, using the same config for PHP/HHVM and Apache2/Nginx as on Heroku", 205 | "homepage": "https://github.com/heroku/heroku-buildpack-php", 206 | "keywords": [ 207 | "apache", 208 | "apache2", 209 | "foreman", 210 | "heroku", 211 | "hhvm", 212 | "nginx", 213 | "php" 214 | ], 215 | "time": "2020-05-26T15:47:09+00:00" 216 | } 217 | ], 218 | "aliases": [], 219 | "minimum-stability": "stable", 220 | "stability-flags": [], 221 | "prefer-stable": false, 222 | "prefer-lowest": false, 223 | "platform": [], 224 | "platform-dev": [] 225 | } 226 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dhtml2pdf 5 | 6 | 7 | 8 | 9 | 47 | 98 | 99 | 100 | 101 |
102 |
103 |
104 |

dhtml2pdf 

105 |
106 |
107 |
108 |
109 |
Convert an HTML from URL to PDF.
110 |
Uses the snappy image & PDF from URL generation PHP library.
111 |
112 |
113 |
114 |
115 |
116 |
Example. Put your own URL:
117 |
118 |
119 |
120 |
121 | 122 |
123 |
124 | Show PDF 125 |
126 |
127 |
128 |
129 | 130 |
131 |
132 | Download PDF 133 |
134 |
135 |
136 |
137 | 138 |
139 |
140 | Show binary 141 |
142 |
143 |
144 |
145 | 146 | 147 | 148 |
149 |
150 |
151 |
152 | 158 |
159 |
160 | 161 |
162 |
163 |
164 |

165 | 166 | Valid XHTML 1.0! 167 |

168 |
169 |
170 | 171 |
172 | 173 | 174 | -------------------------------------------------------------------------------- /lib/bionic/wkhtmltopdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dellos7/dhtml2pdf/c0c57e0578013749953e6512e1105dfd2298a488/lib/bionic/wkhtmltopdf -------------------------------------------------------------------------------- /lib/xenial/wkhtmltopdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dellos7/dhtml2pdf/c0c57e0578013749953e6512e1105dfd2298a488/lib/xenial/wkhtmltopdf -------------------------------------------------------------------------------- /src/DHtml2Pdf/ApiUtils.php: -------------------------------------------------------------------------------- 1 | 'error', 91 | 'message' => $errorMessage 92 | ); 93 | header('Access-Control-Allow-Origin: *'); 94 | header('Content-type: application/json'); 95 | echo json_encode( $error ); 96 | } 97 | 98 | } -------------------------------------------------------------------------------- /src/DHtml2Pdf/DHtml2Pdf.php: -------------------------------------------------------------------------------- 1 | pdf =$this->getWkhtmltopdfFromCurrentOs(); 31 | } 32 | 33 | public function getWkhtmltopdfFromCurrentOs() { 34 | switch ( PHP_OS ) { 35 | case "Linux": 36 | /* Ubuntu based */ 37 | if( file_exists("/etc/lsb-release") ){ 38 | $codename = parse_ini_string(shell_exec('cat /etc/lsb-release'))['DISTRIB_CODENAME']; 39 | $wkhtmltopdfPath = sprintf( WkhtmltopdfOSDriverEnum::LINUX, $codename ); 40 | /* CentOS based --> https://wkhtmltopdf.org/downloads.html */ 41 | /* Download binary installer and: 42 | yum install xorg-x11-fonts-75dpi 43 | rpm -i /path/to/wkhtmltox-0.12.6-1.centos7.x86_64.rpm 44 | */ 45 | } else if( file_exists( "/etc/centos-release" ) ){ 46 | $wkhtmltopdfPath = "/usr/local/bin/wkhtmltopdf"; 47 | } 48 | if( file_exists( $wkhtmltopdfPath ) ) { 49 | return new Pdf( $wkhtmltopdfPath ); 50 | } 51 | break; 52 | case "Darwin": 53 | if( file_exists( WkhtmltopdfOSDriverEnum::OSX ) ) { 54 | return new Pdf( WkhtmltopdfOSDriverEnum::OSX ); 55 | } 56 | break; 57 | } 58 | throw new WkhtmltopdfDriverNotFoundException(); 59 | } 60 | 61 | public function convertHtml2PdfFromUrl( $url ) { 62 | if( $url ) { 63 | return $this->pdf->getOutput( $url ); 64 | } 65 | throw new InvalidArgumentException( 'The param \'url\' is required.' ); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/DHtml2Pdf/Exception/WkhtmltopdfDriverNotFoundException.php: -------------------------------------------------------------------------------- 1 | message ); 19 | parent::__construct($message, $code, $previous); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/autoload.php: -------------------------------------------------------------------------------- 1 |