はじめに
GoでHTMLからPDF出力する方法をまとめました。
環境構築
wkhtmltopdfのインストール
wkhtmltopdfというCLIツールをGoから呼ぶことになるので、
まずはこちらをインストールします。
公式のDownloadsから、自分の環境にあったものを選択しましょう。
※macの場合は、brew caskでインストール可能が可能です。
brew cask install wkhtmltopdf
Goのライブラリをインストール
今回は、go-wkhtmltopdfを使用します
go get -u github.com/SebastiaanKlippert/go-wkhtmltopdf
ざっくりレシピ
URLから
main.go
package main
import (
"fmt"
"log"
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
func main() {
// Create new PDF generator
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
url := "https://google.com/"
pdfg.AddPage(wkhtmltopdf.NewPage(url))
// PDF作成
err = pdfg.Create()
if err != nil {
log.Fatal(err)
}
// 出力
err = pdfg.WriteFile("./google.pdf")
if err != nil {
log.Fatal(err)
}
fmt.Println("tada!")
}
結果
ファイルから
main.go
package main
import (
"fmt"
"log"
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
func main() {
// Create new PDF generator
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
p := "./test.html"
pdfg.AddPage(wkhtmltopdf.NewPage(p))
// PDF作成
err = pdfg.Create()
if err != nil {
log.Fatal(err)
}
// 出力
err = pdfg.WriteFile("./test.pdf")
if err != nil {
log.Fatal(err)
}
fmt.Println("tada!")
}
HTML文字列から
main.go
package main
import (
"fmt"
"log"
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
"strings"
)
func main() {
// Create new PDF generator
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
html := `
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>こんにちは!!!</h1>
</body>
</html>`
pdfg.AddPage(wkhtmltopdf.NewPageReader(strings.NewReader(html)))
// PDF作成
err = pdfg.Create()
if err != nil {
log.Fatal(err)
}
// 出力
err = pdfg.WriteFile("./test.pdf")
if err != nil {
log.Fatal(err)
}
fmt.Println("tada!")
}
結果
複数のHTML文字列の場合
こちら、複数のHTMLを渡して、ページをうまいこと分けてくれないかなと思ったのですが、
もとのCLIツールの実装的に難しいそうです(標準入力は一つしか受け取れないので、、、)
参考:
https://github.com/SebastiaanKlippert/go-wkhtmltopdf/issues/7#issuecomment-293183363
なので、代替案として ファイルに一度出力してから、そのパスを指定する
が良さそうです。
main.go
package main
import (
"fmt"
"log"
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
func main() {
// Create new PDF generator
pdfg, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
log.Fatal(err)
}
tmp1 := "./tmp/tmp1.html"
tmp2 := "./tmp/tmp2.html"
tmp3 := "./tmp/tmp3.html"
pdfg.AddPage(wkhtmltopdf.NewPage(tmp1))
pdfg.AddPage(wkhtmltopdf.NewPage(tmp2))
pdfg.AddPage(wkhtmltopdf.NewPage(tmp3))
// PDF作成
err = pdfg.Create()
if err != nil {
log.Fatal(err)
}
// 出力
err = pdfg.WriteFile("./test.pdf")
if err != nil {
log.Fatal(err)
}
fmt.Println("tada!")
}
このようにすると、3ページに分けてpdfを出力してくれます
おわりに
PDF出力ってレガシーだなと思いつつも、BtoBとかだと避けられなかったりしますよね。
そんな時、こちらの記事がお役に立てば幸いです。