PDFに印刷するときにデフォルトのヘッダー/フッターを変更します
Google ChromeをPhantomJSの代替として使用して、HTMLをPDFにレンダリングしようとしています。これまでのところ、私にとってはうまく機能しています。私が持っている唯一の問題は、次のPhantomJSコードを翻訳する方法を見つけていないことです。
page.paperSize = {
footer: {
contents: phantom.callback(function(pageNum, numPages) {
return "Power by MyWebsite. Created on "+formatDate(new Date())+"<span style='float:right'>" + pageNum + " / " + numPages + "</span>";
})
}
}
日付のフォーマットは、質問と同じ機能です JavaScript日付のフォーマット方法
ただし、Google Chromeでこの動作をヘッドレスで再現する方法を見つけていません。 https://github.com/cyrus-and/chrome-remote-interface からChromeリモートインターフェイス(CDP)を使用しています
これは、私のchromeリモートインターフェイスコードの概要です。
return new Promise(async function (resolve, reject) {
const url = "<MyURL here>";
const [tab] = await Cdp.List()
const client = await Cdp({ Host: '127.0.0.1', target: tab });
await Promise.all([
Network.enable(),
Page.enable()
]);
Page.loadEventFired(function () {
setTimeout(function () {
resolve(Page.printToPDF({displayHeaderFooter:true}))); //https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF
}, 3000);
});
await Page.navigate({ url });
};
PDFは問題なく取得できますが、デフォルトのChromeヘッダーとフッターしか取得できません。それらを変更する方法はありますか?
注:ページ内でJavaScriptを使用して各ページの下部に要素を追加できることを認識していますが、フッターを変更したいエクスポート/印刷時にブラウザによって追加されます。これは、ページ内の他のdivの奇妙なリフローを引き起こすことなく、正しく配置されることがはるかに信頼できるためです。
これは質問の更新/回答です。 Chromium 64以降、headerTemplate
およびfooterTemplate
パラメーターをprintToPDF
に使用することができます
chrome remote interface を使用すると、動作するはずのサンプルコードがあります。
return new Promise(async function (resolve, reject) {
const url = "<MyURL here>";
const [tab] = await Cdp.List()
const client = await Cdp({ Host: '127.0.0.1', target: tab });
await Promise.all([
Network.enable(),
Page.enable()
]);
Page.loadEventFired(function () {
setTimeout(function () {
//https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF
resolve(Page.printToPDF({
displayHeaderFooter:true,
footerTemplate: "<span class='pageNumber'> of <span class='totalPages'>"
})));
}, 3000);
});
await Page.navigate({ url });
};
<header>
および<footer>
タグを使用して、カスタムヘッダーとフッターを作成することができます。 ChromeHeadless。Firefoxではテストしていません。IEなど...
<header>
Custom Header
<img src="http://imageurl.com/image.jpg"/>
</header>
<div class="content">Page Content - as long as you want</div>
<footer>
Footer Content
</footer>
cSS
@page {
margin: 0;
}
@media print {
footer {
position: fixed;
bottom: 0;
}
header {
position: fixed;
top: 0;
}
}
@page { margin: 0 }
は、デフォルトのヘッダーとフッターを削除します。
お役に立てれば。
あなたの問題には2つの解決策があります
A)マージンを残さずにchrome-headerを押し出します:
@page {
margin: 0;
size: auto;
}
または
@media print {
@page { margin: 0; }
body { margin: 1.6cm; }
}
B)元々はChromeの世界であるべきFirefoxソリューション
<html moznomarginboxes mozdisallowselectionprint>
いくつかのサンプル:
<!DOCTYPE html>
<html moznomarginboxes mozdisallowselectionprint>
<head>
<title>Print PDF without header</title>
<style>
@media print {
@page { margin: 0; }
body { margin: 1.6cm; }
}
</style>
</head>
<body>
<p>Some Text in Paragraph to print!</p>
<a href="javascript:print()">Print</a>
</body>
</html>
これをハック以外の方法で本当に実行したい場合は、コマンドラインインターフェイスがあまりサポートしていないため、chrome devtoolsプロトコルに通じる必要があります(別名--print-to-pdf
がすべてです。印刷オプションはありません)
プロトコルはここに文書化されています: https://chromedevtools.github.io/devtools-protocol/tot
クライアントライブラリは多くの言語で利用可能で、パッケージマネージャーを介して利用できます。
使用法を示すためにまとめたいくつかの例を次に示します。
- PHP: https://github.com/jehoshua02/experiment-chrome-devtools-protocol-php
- ノード: https://github.com/jehoshua02/experiment-chrome-remote-interface-node
Page.printToPDF
プロトコルメソッドは、ヘッダーとフッターのカスタムマークアップを渡すための引数をサポートします。
基本的に、プロトコルはprotocol.json
。クライアントライブラリが、アプリケーションで使用するクラス/メソッドを生成するために使用します。これらのメソッドは、プロトコルとの低レベルの通信をカプセル化します。
クライアントライブラリパッケージを(npmまたはcomposerを介して)インストールし、chromeがインストールされていることを確認し、小さなコードを記述すれば、ヘッダー/フッターのないPDFを生成できました。素晴らしい。
箱から出してすぐに動作するものが必要な場合は、apokryfosの答えに基づいて、今日書いたスクリプトを共有したいと思います。
最初に、依存関係をインストールする必要があります
yarn global add chrome-remote-interface
次に、デバッグポートを有効にしてヘッドレスクロムを起動する必要があります
chromium-browser --headless --disable-gpu --run-all-compositor-stages-before-draw --remote-debugging-port=9222
今、あなたは私のスクリプトを保存する必要がありますprint-via-chrome.js
:
#!/usr/bin/env node
const homedir = require('os').homedir();
const CDP = require(homedir+'/.config/yarn/global/node_modules/chrome-remote-interface/');
const fs = require('fs');
const port = process.argv[2];
const htmlFilePath = process.argv[3];
const pdfFilePath = process.argv[4];
(async function() {
const protocol = await CDP({port: port});
// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page} = protocol;
await Page.enable();
Page.loadEventFired(function () {
console.log("Waiting 100ms just to be sure.")
setTimeout(function () {
//https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF
console.log("Printing...")
Page.printToPDF({
displayHeaderFooter: true,
headerTemplate: '<div></div>',
footerTemplate: '<div class="text center"><span class="pageNumber"></span></div>',
//footerTemplate: '<div class="text center"><span class="pageNumber"></span> of <span class="totalPages"></span></div>'
}).then((base64EncodedPdf) => {
fs.writeFileSync(pdfFilePath, Buffer.from(base64EncodedPdf.data, 'base64'), 'utf8');
console.log("Done")
protocol.close();
});
}, 100);
});
Page.navigate({url: 'file://'+htmlFilePath});
})();
chmod +x print-via-chrome.js
で実行可能にすると、次のようにhtmlファイルをpdfファイルに変換できるはずです。
./print-via-chrome.js 9222 my.html my.pdf
変換が完了したら、クロムを終了することを忘れないでください。
このソリューションは完璧からはほど遠いものと確信していますが、少なくとも機能し、この機能について多くの質問を見て、それを機能させるために数時間を費やさなければならなかったので、ソリューションを共有したいと思いました。空のテンプレートは既存のテンプレートに置き換わらないように見えるため(<div></div>
が必要)、新しいテンプレートは別のドキュメントに記載されているまで、header-およびfooterTemplatesに関連する問題がいくつかあります。 <div class="text center">
または同様のものでラップされます。
このフォーラム によると、現時点ではGoogle Chromeでこれを行う方法はありません。ヘッダー/フッターをオンまたはオフにするだけです。これはコメントによって示されます:
現在、ドキュメントを印刷するときにヘッダーを編集する方法はありません。現在、ヘッダーとフッターのオン/オフを切り替えることができるのは、日付、Webページの名前、ページURL、および印刷するドキュメントのページ数だけです。 Chrome Webストアをチェックして、Chromeにインストールできる便利なサードパーティ製拡張機能があるかどうかを確認してください。印刷- ソース
あなたが探している機能を得るためのサードパーティの拡張機能があるかもしれませんし、あなたが提案するように、あなたは印刷したい要素を追加するためにJavaScriptを使うことができます。