[php] phpwkhtmltopdf 패키지 설치와 사용방법

PDF관련 여러 패키지 문서를 확인해 보고 간단히 테스트 해봤지만 ‘phpwkhtmltopdf’ 만한 패키지가 없는것 같다.

요구사항

phpwkhtmltopdf 패키지는 wkhtmltopdf 라이브러리를 의존 하고 있기 때문에 반드시 설치 해야한다

apt-get insall wkhtmltopdf 으로 설치하게 되면 phpwkhtmltopdf 패키지의 PDF 병합 기능을 사용 할수 없으므로 공식사이트에서 제공 하는 설치파일로 설치하는것이 좋다.

  • wkhtmltopdf 의존성 패키지 설치
apt-get update && apt-get install -y \
        libfreetype6-dev \
        libfontconfig \
        zlib1g \
        libxrender1 \
        libxext6 \
        libx11-6 \
        fontconfig \
        xfonts-75dpi \
        xfonts-base
  • wkhtmltopdf 설치
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb

dpkg -i 'wkhtmltox_0.12.6-1.buster_amd64.deb'
  • phpwkhtmltopdf 설치
composer require mikehaertl/phpwkhtmltopdf

사용방법

  • 기본사용
use mikehaertl\wkhtmlto\Pdf;

// You can pass a filename, a HTML string, an URL or an options array to the constructor
$pdf = new Pdf('/path/to/page.html');

// On some systems you may have to set the path to the wkhtmltopdf executable
// $pdf->binary = 'C:\...';

if (!$pdf->saveAs('/path/to/page.pdf')) {
    $error = $pdf->getError();
    // ... handle error here
}
  • 커버 & table of content & PDF 이어붙이기
use mikehaertl\wkhtmlto\Pdf;

$pdf = new Pdf;
$pdf->addPage('/path/to/page.html');
$pdf->addPage('<html>....</html>');
$pdf->addPage('http://www.example.com');

// Add a cover (same sources as above are possible)
$pdf->addCover('/path/to/mycover.html');

// Add a Table of contents
$pdf->addToc();

// Save the PDF
if (!$pdf->saveAs('/path/to/report.pdf')) {
    $error = $pdf->getError();
    // ... handle error here
}

// ... or send to client for inline display
if (!$pdf->send()) {
    $error = $pdf->getError();
    // ... handle error here
}

// ... or send to client as file download
if (!$pdf->send('report.pdf')) {
    $error = $pdf->getError();
    // ... handle error here
}

// ... or you can get the raw pdf as a string
$content = $pdf->toString();
  • 이미지 생성
use mikehaertl\wkhtmlto\Image;

// You can pass a filename, a HTML string, an URL or an options array to the constructor
$image = new Image('/path/to/page.html');
$image->saveAs('/path/to/page.png');

// ... or send to client for inline display
if (!$image->send()) {
    $error = $image->getError();
    // ... handle error here
}

// ... or send to client as file download
if (!$image->send('page.png')) {
    $error = $image->getError();
    // ... handle error here
}

PDF 한글이 깨지는 경우 한글 폰트를 설치하면 됨
링크 참고

apt-get install fontconfig
curl -o nanumfont.zip http://cdn.naver.com/naver/NanumFont/fontfiles/NanumFont_TTF_ALL.zip
unzip -d /usr/share/fonts/nanum nanumfont.zip
fc-cache -f -v

PDF 관련 패키지 리스트


바로 테스트하기 (도커 설치 필수)

https://github.com/jisung87kr/docker_phpwkhtmltopdf

[php]php를 이용한 웹크롤링

의존성

composer.json

{
    "require": {
        "guzzlehttp/guzzle": "^7.0",
        "symfony/dom-crawler": "^5.3",
        "symfony/css-selector": "^5.3"
    }
}

요청과 응답페이지 요소탐색

use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;

$url = 'http://ujsstudio.com';
$client = new Client();
$res = $client->get($url);
$res = $res->getBody();
$html = (string)$res; // 문자열로 형변환
// dom 필터링
$crawler = new Crawler($html);
$nodeValues = $crawler->filter("#primary a")->each(function(Crawler $node, $i){
    return $node->attr('href');
});

페이지네이션 처리

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Symfony\Component\DomCrawler\Crawler;

$result = [];
$client = new Client();

// 페이지 조회 익명함수(제너레이터) 생성
$requests = function ($total) use ($client) {
    $uri = 'http://ujsstudio.com/page';
    for ($i = 0; $i < $total; $i++) {
        yield function() use ($client, $uri, &$i) {
            $uri = $uri.'/'.$i+1;
            return $client->getAsync($uri);
        };
    }
};

$pool = new Pool($client, $requests(10), [
        'concurrency' => 5,
        'fulfilled' => function (Response $response, $index) use (&$result) {
            $res = $response->getBody();
            $html = (string)$res;

            // 요소탐색
            $crawler = new Crawler($html);
            $nodeValues = $crawler->filter("#primary a")->each(function(Crawler $node, $i){
                return $node->attr('href');
            });

            $result[] = $nodeValues;
        },
        'rejected' => function (RequestException $reason, $index) {
            // this is delivered each failed request
        },
]);

$promise = $pool->promise();
$promise->wait();

[composer] autoload

composer를 사용해서 간단하게 autoload를 사용하는 방법

1. monolog 패키지 설치해보기

composer require monolog/monolog

2. 패키지 로드하기

index.php

<?php
include './vendor/autoload.php';

use Monolog\Logger;

$log = new Logger('name');

3. 내 클래스 로드해보기

컴포저 autoload는 psr-4 규칙을 따르고 있기 때문에 클래스 생성시 네임스페이스를 규칙에 맞게 정하고 composer.json 파일에 namespace prefix와 클래스를 정의한 디렉토리를 매핑해주는 설정을 추가한다.

composer.json

{
    "require": {
        "monolog/monolog": "^2.2"
    },
    "autoload": {
        "psr-4": { // Js 네임페이스 접두사를 lib에 매핑
            "Js\\" : "lib/" 
        }
    }
}
/lib/src/Foo.php

<?php
namespace Js\Src;

class Foo{
    public function say()
    {
        return 'hello';
    }
}
index.php

<?php
include './vendor/autoload.php';

use Monolog\Logger;
use Js\Src\Foo;

$log = new Logger('name');
$foo = new Foo();
echo $foo->say();
composer dump-autoload

Foo 클래스에서 사용한 Js 네임스페이스 접두사를 lib디렉토리에 매핑해 주었기 때문에 autoload가 실행 될때 자동으로 지정한 경로의 클래스를 로드할 수 있게 된다.

참조

  • composer.json schema
  • psr-4
  • http://blog.ujsstudio.com/2021/01/09/psr-4-%eb%84%a4%ec%9e%84%ec%8a%a4%ed%8e%98%ec%9d%b4%ec%8a%a4-%ea%b7%9c%ec%b9%99/

[composer] file could not be downloaded (http/1.1 404 not fund) 해결방법

라라벨 설치하는 과정에서 아래와 같은 에러 발생

 [Composer\Downloader\TransportException]
  The "https://packagist.org/p/provider-2020-01%24d05e2d9aae910523f4e326c5a73b6cc7b6d498492a6f115892377153193c21bd.js
  on" file could not be downloaded (HTTP/1.1 404 Not Found)

아래의 명령어를 순서대로 입력후 재설치

composer clear-cache
composer -vvv

참조:
https://github.com/composer/composer/issues/7021