ソースコードから理解する技術-UnderSourceCode

手を動かす(プログラムを組む)ことで技術を理解するブログ

go-wkhtmltopdfでPDFを出力してみる

GolangでPDFを出力するためのライブラリとして
GitHub - SebastiaanKlippert/go-wkhtmltopdf: Golang commandline wrapper for wkhtmltopdf
があります。

単純な使用例は上記のGithub内にもあるのですが
今回は実案件で使用することを想定し

  • HTMLをPDFに変換してくれるが、そのHTMLの定義にテンプレートを使った
  • ロゴなどを印字することを想定してimgタグにて読み込んだ画像がPDFに出した

をやってみました。

ソース、テンプレートは以下のようになりました。
テンプレートのimgタグのsrcには、好きな画像のURLなどを入れてみてください。

package main

import (
	"bytes"
	"fmt"
	"html/template"
	"log"
	"strings"

	wkhtmltopdf "github.com/SebastiaanKlippert/go-wkhtmltopdf"
)

type templateData struct {
	Datas []data
}

type data struct {
	Name string
	Cal  string
}

func main() {
	datas := make([]data, 0)
	datas = append(datas, data{Name: "M16", Cal: "5.56"})
	datas = append(datas, data{Name: "AK47", Cal: "7.62"})
	datas = append(datas, data{Name: "MP5", Cal: "9.00"})
	tmplData := templateData{Datas: datas}

	t := template.Must(template.ParseFiles("sample.tpl"))

	var tpl bytes.Buffer
	if err := t.Execute(&tpl, tmplData); err != nil {
		log.Fatal(err)
	}
	html := tpl.String()

	pdfg := wkhtmltopdf.NewPDFPreparer()
	pdfg.AddPage(wkhtmltopdf.NewPageReader(strings.NewReader(html)))
	pdfg.Dpi.Set(600)

	jsonBytes, err := pdfg.ToJSON()
	if err != nil {
		log.Fatal(err)
	}
	pdfgFromJSON, err := wkhtmltopdf.NewPDFGeneratorFromJSON(bytes.NewReader(jsonBytes))
	if err != nil {
		log.Fatal(err)
	}

	err = pdfgFromJSON.Create()
	if err != nil {
		log.Fatal(err)
	}

	err = pdfgFromJSON.WriteFile("./sample.pdf")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("print done, pdf size %d bytes", pdfgFromJSON.Buffer().Len())
}
<!doctype html>
<style>
.table {
    border-collapse:collapse;
    border-spacing:0px; 
    border:1px solid #FF0000;
}

.table tr td:nth-child(1) {
    width:300px;
}

.table tr td {
    border:1px solid #000000;
}
</style>
<html>
    <head>
        <title>PRINT PDF TEST</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
    <table class="table">
        <tr>
            <td>品名</td>
            <td>口径</td>
        </tr>
        {{range $i, $data := .Datas}}
            <tr>
                <td>{{$data.Name}}</td>
                <td>{{$data.Cal}}</td>
            </tr>
        {{end}}
    </table>
    <br>
    <img src="your favorite img" />
    </body>
</html>

テンプレートと出力したいデータを定義し
tpl.String()」でテンプレートからhtml形式の文字列を取得しています。
このhtml形式の文字列をgo-wkhtmltopdfに渡すことで、PDFに出力しています。

今回作成したソースは以下となります。
GitHub - SrcHndWng/go-wkhtmltopdf-sample