Developer's Blog

puppeteer で Chrome の Headless を利用して、PDF を作成する

こんにちは、エンジニアの上田です。

Chrome の Headless で、スクレイピングで特定の URL のスクリーンショットやファイルのダウンロードを試した方がいるのではないでしょうか?

今回は、Chrome の Headless を操作する Node ライブラリの puppeteer で、ローカルに SVG ファイルを置いて、PDF ファイルを作成する例を紹介したいと思います。

puppeteer 自体の説明は、 GitHub – GoogleChrome/puppeteer: Headless Chrome Node API をご参考ください。

環境構築

この記事では、Ubuntu Server 16 をセットアップ直後からの内容になります。
※Amazon Linux でも試してみましたが、Google Chrome が yum では入らなかったため、Ubuntu Server で試しています。
また、Windows でも動作することを確認しました。

Node.js の導入

puppeteer を利用するには、Node.js が必要になりますので、以下のようにして導入しています。

$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt-get install nodejs

puppeteer の導入

この記事では、以下のように “TestPDF” フォルダを作り、そこに導入して試します。

$ mkdir ~/TestPDF
$ cd ~/TestPDF
$ npm i puppeteer

最新バージョンの puppeteer v0.13.0 では、”~/TestPDF/node_modules/puppeteer/.local-chromium/” フォルダに、puppeteer に対応している Chromium がダウンロードされており、
別途、Google Chrome / Chromium を用意しなくても動作することを確認しました。

Node.js で実行するスクリプトの準備

以下のようなスクリプトを用意します。
※便宜上、createPDF.js として準備しました。
※スプリプトの引数は、URL, 出力ファイル, 用紙のサイズ, 用紙の縦横指定としています。

const puppeteer = require('puppeteer');

async function main(url, outputFile, paperW, paperH, orientation) {
	const browser = await puppeteer.launch();
	const page = await browser.newPage();
	await page.goto(url, {waitUntil:['networkidle0'], timeout:10000});
	await page.setViewport({
		width: Number(paperW),
		height: Number(paperH),
	});
	await page.pdf({
		path: outputFile,
		width: paperW, 
		height: paperH,
		landscape: orientation=='portrait'? false : true,
	});
	await browser.close();
}

if (process.argv.length < 5) {
	console.log('arguments error.');
	return;
}

var url = process.argv[2];
var outputFile = process.argv[3];
var paperWH = process.argv[4];
var orientation = process.argv[5];

var arrPaperWH = paperWH.split('*');
var paperW = arrPaperWH[0];
var paperH = arrPaperWH[1];

main(url, outputFile, paperW, paperH, orientation);

上記のスクリプトで利用している API は、puppeteer.launch, browser.newPage, page.goto, page.pdf などですが、API の説明は Puppeteer API v1.0.0-rc をご参考ください。

PDF ファイルにしたい内容の SVG ファイルの用意

PDF ファイルにしたい内容の SVG ファイルを用意します。
※便宜上、test.svg として準備しました。
※表示内容は、幅 1000px, 高さ 2000px に赤と青の四角形を表示する内容としています。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:xlink="http://www.w3.org/1999/xlink"
        width="1000" height="2000" overflow="visible">
        <rect fill="rgba(255,0,0,1)" width="500" height="500" y="0" x="0"></rect>
        <rect fill="rgba(0,0,255,1)" width="500" height="500" y="1500" x="500"></rect>
</svg>

スプリプトの実行

用意したスクリプト と SVG ファイルを実行させます。

$ node createPDF.js file:///home/username/TestPDF/test.svg output.pdf 1000*2000 portrait
# URL の部分は、フルパスが必要になりますので、ユーザー名の部分は "username" に変更しています。

作成した PDF ファイルの内容

最後に

ご紹介した内容は、事前に用意した SVG ファイルを Chrome の Headless で PDF ファイルを作ったため、固定的な出力になりましたが、
SVG ファイルをプログラム的に作成したりすると、任意の PDF ファイルの作成ができます。

Chrome の Headless の利用としては、スクレイピングで外の URL を操作するイメージがあると思いますが、ご紹介した内容のようにローカルファイルにも利用できますので、色々な用途を考えてみては如何でしょうか?

ソーシャルアカウント

フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!

Copyright © 2019 Fenrir Inc. All rights reserved.