[컴][웹] laravel 에서 pdf download

 라라벨 php / laravel download / ajax pdf download /snappy 

laravel 에서 pdf download

pdf 생성

wkhtmltopdf 을 이용해서 pdf 를 생성할 수 있다. pdf 생성은 ref.2 를 참고하자.

아래는 wkhtmltopdf 을 이용해서 pdf 를 생성하고, 그것을 download 로 제공해주는 laravel api 의 controller 부분이다. pdf library 는 snappy 를 사용했다.

...
use Knp\Snappy\Pdf;

class MypageController extends ApiController
{
    ...
    public function getGenPdfDownload(Request $request)
    {
        \Validator::make($request->all(), [
            'start_date' => ['required', 'date'],
            'end_date' => ['required', 'date', 'after_or_equal:start_date'],
        ])->validate();

        $wkhtmltoxPath = env('WKHTMLTOPDF_PATH', '/usr/local/bin/wkhtmltopdf');
        $snappy = new Pdf($wkhtmltoxPath);

        $pdfPath = public_path("tmp-download/dummy_".time().".pdf");
        $snappy->generateFromHtml(
            '<head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
            </head>
            <body>
                <div>test</div>
            </body>', $pdfPath);

        $newFileName = 'test-pdf-file-'.time().'.pdf';
        $headers = [
            'Content-Type' => 'application/pdf; charset=utf-8',
            'App-Download-Filename' => urlencode($newFileName),
            'Content-Transfer-Encoding' => 'binary',
            'Cache-Control' => 'no-cache private'
        ];


        return response()->download($pdfPath, $newFileName, $headers)->deleteFileAfterSend(true);
    }
}

ajax download with responseType: 'blob'

axios 를 사용한 ajax 사용법이다. 주의할 점은 responseType: 'blob' 을 넣어줘야 한다는 것이다. 그렇지 않으면 계속 제대로 된 download 가 되지 않는다.

이유는 아마도 ref. 2에서 이야기하는 것처럼 `responseType: ‘blob’ 가 없이 download 를 한 결과를 Blob 으로 넣게 되면 js 가 이것을 UTF8 encoding 으로 인식하는 듯 하다. 그래서 size 가 더 크고 정상적이지 않은 file 이 생성된다.

이것은 `responseType: ‘blob’ 가 없이 받은 후에 Unit8Array 를 이용해서 Blob 에 넣어도 마찬가지였다. 이때는 size 가 비슷해졌기는 하지만 몇몇부분이 빠져서 제대로 되지 않은 file 이 만들어졌다.

const axios = require('axios');

axios({
        method: 'get',
        url: '/myhost.me/pdfdownload',
        responseType: 'blob'
}).then(res => {
  if (res) {
    const blob = new Blob([res.data], {
      type: res.headers['content-type']
    })
    const link = document.createElement('a')
    link.href = window.URL.createObjectURL(blob)
    link.download = decodeURI(res.headers['app-download-filename'])
    link.click()
    URL.revokeObjectURL(link.href)
  } else {
    console.error('다운로드 실패')
  }
  this.getList()
})
.catch(error => {
  console.log(error)
});

See Also

  1. lumen 5.4 에서 excel download 만들기
  2. php 에서 snappy 사용(pdf 생성 library)
  3. elastic beanstalk에서 wkhtmltopdf 설치하기

References

  1. Sending and Receiving Binary Data - Web APIs | MDN
  2. JavaScript BLOB coming out much larger than the input - Stack Overflow
  3. axios examples

댓글 없음:

댓글 쓰기