はじめに
ElectronアプリからPDF出力するときに、PDFにページ番号を付けられるようになりました。これは、Electronのversionが21以降でprintToPDF()
関数の仕様が変わったためです。
いくつか試行錯誤も必要だったので、ここで共有します。
条件と必要なこと
- PDFの出力は
webContents.printToPDF()
関数を用いている。 - Electronのversionを21以上にする。一方で、versionを上げることによるAPIの変更もあるので気をつけましょう。公式の破壊的変更を参考にするとよいと思います。
コードの主な修正法
version 20以前のコードで次のようにしてPDFを出力していたとしましょう
const wc = mainWindow.webContents;
wc.printToPDF({pageSize:"A4", marginsType:0}).then(data => {
fs.writeFile(result.filePath, data, (error) => {
if (error) throw error;
console.log('Write PDF successfully.');
})
}).catch(error => {
console.log(error);
});
三行目以降は皆さんのアプリでやりたいことに依存していると思いますが、シンプルにすると上記のような感じでしょう。
PDFの出力に関する設定は、2行目のprintToPDF
関数の第一引数でした。Electronのversion 21以降では、ここの書式が変更になりました。例えば
-
marginsType
の廃止 -
margins
の追加 -
headerTemplate
の追加 -
footerTemplate
の追加
などです。今回は、このheaderTemplate
やfooterTemplate
を使って、PDFにページ番号を出力します。これらには文字列としてHTML要素を渡すことができます。
今回はfooterにページ番号を表示し、headerには何も表示しないことにします。私の場合は、上記のコードを次のように変更しました。変更部分は、printToPDF
関数の第一引数のみです。
const headerHTML = "<div></div>"; //空文字ではheaderにdefault文字が出てしまう//
const footerHTML = "<div style=\"width:100%; text-align: center; font-size: 8pt; font-family: 'Times', 'Times New Roman', 'serif';\"><span class=pageNumber></span></div>";
const wc = mainWindow.webContents;
wc.printToPDF({pageSize:"A4",
margins:{top:0,bottom:0,left:0,right:0},
displayHeaderFooter: true,
headerTemplate:headerHTML,
footerTemplate:footerHTML}).then(data => {
fs.writeFile(result.filePath, data, (error) => {
if (error) throw error;
console.log('Write PDF successfully.');
})
}).catch(error => {
console.log(error);
});
変更点及び注意点は次の通りです。
-
marginsType
の廃止に伴い、margins
にて0をセットする。実際の余白は、CSSで設定しているためです。 -
displayHeaderFooter: true
これを記述しないと、headerやfooterが表示されません。 -
headerTemplate:headerHTML
今回はheaderには何も表示したくありません。headerHTML
文字列変数を通じて空のdiv
要素を入れることで、表示を空にしています。注意点として、空文字""
などをセットしても、デフォルトでタイプスタンプやファイル名が指定されてしまいます。 -
footerTemplate:footerHTML
フッター用のHTMLを文字列として渡します。文字列変数footerHTML
に一度文字列をセットしてから、printToPDF
関数の引数に渡せます。
さて、footerTemplate
にセットするフッター用のHTMLでは、「ページ番号」と「スタイル」を両方指定します。
- ページ番号は
<span class=pageNumber></span>
とすることで挿入されます。 - この他にも全ページ数などの情報が埋め込めます。詳しくはElectronのAPIを参照されたし。
また、スタイルに関してはCSSファイルとして渡すことができなかったので、仕方なくdiv
タグのstyle
プロパティーとして直書きしています。気づいた注意点は以下の点です。
- デフォルトのフォントが非常に小さいので、
font-size
は必ず指定したほうが良い。 - フォントファミリーとして、
Times New Roman
が効かないので、Times
も指定すること。私の環境ではserif
も効かなかった。
以上で、ページ番号がPDFに埋め込めるようになりました。
おわりに
PDFへのページ番号の表示は長年待っていた機能だったので嬉しいですね。ただし、直接印刷するwebContents.print()
関数の方では、第一引数のオプションが異なり、ページ番号を入れられるかどうか不明です。