Goを用いてPDFを操作する機会があったため、gofpdfの使い方についてまとめる。

gofpdf とは

https://github.com/jung-kurt/gofpdf/

gofpdfはPDFを生成するgoのライブラリ。テキスト、図面、イメージを実装し ている。READMEに実装している機能が記載されている。

Features

  • Choice of measurement unit, page format and margins

  • Page header and footer management

  • Automatic page breaks, line breaks, and text justification

  • Inclusion of JPEG, PNG, GIF, TIFF and basic path-only SVG images

  • Colors, gradients and alpha channel transparency

  • Outline bookmarks

  • Internal and external links

  • TrueType, Type1 and encoding support

  • Page compression

  • Lines, Bézier curves, arcs, and ellipses

  • Rotation, scaling, skewing, translation, and mirroring

  • Clipping

  • Document protection

  • Layers

  • Templates

  • Barcodes

README.md抜粋

  • 測定単位、ページフォーマット、マージンの選択

  • ページヘッダーとフッターの管理

  • 自動ページ区切り、改行、およびテキストの位置揃え

  • JPEG、PNG、GIF、TIFF、および基本的なパスのみのSVG画像を含める

  • 色、グラデーション、アルファチャンネルの透明度

  • ブックマークの概要

  • 内部および外部リンク

  • TrueType、Type1、およびエンコーディングのサポート

  • ページ圧縮

  • 線、ベジエ曲線、円弧、楕円

  • 回転、スケーリング、スキュー、変換、ミラーリング

  • クリッピング

  • 文書保護

  • レイヤー

  • テンプレート

  • バーコード

かなり高機能でいろいろと実装されている。

簡単な使い方

まずはREADMEに記載されている例から試す。"Hello, world" という文字だけ が記述されたPDFを生成する。

hello.go

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
)

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetFont("Arial", "B", 16)
	pdf.Cell(40, 10, "Hello, world")
	err := pdf.OutputFileAndClose("hello.pdf")
	if err != nil {
		fmt.Printf("error\n")
	}
}

一行ずつ見ていく。

	pdf := gofpdf.New("P", "mm", "A4", "")

Fpdfを生成してそのポインタを返す。第1引数はorientationStrで、デフォル トのページ方向を指定する。PはPortrait(縦)、LはLandscapeです(横)。空の 文字列はPになる。第2引数はunitStrで、要素のサイズパラメータで使用され る長さの単位を指定する。ここではミリメートルを指定する。空の文字列はmm になる。他にpt, cm, in(インチ)が指定できる。第3引数はsizeStr。"A3", "A4", "A5" などを指定する。第4引数はfontDirStr、フォントが格納されてい るディレクトリのパスを指定する。

	pdf.AddPage()

AddPage()はページを追加する。追加したページが編集対象のページになる。

デバッグコードがコメントアウトされて残っている。 https://github.com/jung-kurt/gofpdf/blob/1bef4f81c40b64d68788e590003f4f8fbdc4d296/fpdf.go#L714

	pdf.SetFont("Arial", "B", 16)

SetFont()はフォントの設定。第1引数はfamilyStr、フォントファミリーを指 定する。第2引数はstyleStr、"B" (bold), "I" (italic), "U" (underscore) を指定する。"BI"のように組み合わせて指定もできる。第3引数はsize、文字 サイズを指定する。

	pdf.Cell(40, 10, "Hello, world")

Cell()でセルを追加する。セルは文字などの表示領域。第1引数で幅、第2引数 で高さを指定する。第3引数は挿入する文字列を指定する。

	err := pdf.OutputFileAndClose("hello.pdf")

OutputFileAndClose()はPDFをファイルに出力してファイルをクローズする。 第1引数に出力するファイルパスを指定する。

go run hello.go

これを実行するとhello.pdfが出力する。

Fpdfの構造

// Fpdf is the principal structure for creating a single PDF document
type Fpdf struct {
	page             int                       // current page number
	n                int                       // current object number
	offsets          []int                     // array of object offsets
	templates        map[int64]Template        // templates used in this document
	templateObjects  map[int64]int             // template object IDs within this document
	buffer           fmtBuffer                 // buffer holding in-memory PDF
	pages            []*bytes.Buffer           // slice[page] of page content; 1-based
	state            int                       // current document state
	compress         bool                      // compression flag
	k                float64                   // scale factor (number of points in user unit)
	defOrientation   string                    // default orientation
	curOrientation   string                    // current orientation
	stdPageSizes     map[string]SizeType       // standard page sizes
	defPageSize      SizeType                  // default page size
	curPageSize      SizeType                  // current page size
	pageSizes        map[int]SizeType          // used for pages with non default sizes or orientations
	unitStr          string                    // unit of measure for all rendered objects except fonts
	wPt, hPt         float64                   // dimensions of current page in points
	w, h             float64                   // dimensions of current page in user unit
	lMargin          float64                   // left margin
	tMargin          float64                   // top margin
	rMargin          float64                   // right margin
	bMargin          float64                   // page break margin
	cMargin          float64                   // cell margin
	x, y             float64                   // current position in user unit
	lasth            float64                   // height of last printed cell
	lineWidth        float64                   // line width in user unit
	fontpath         string                    // path containing fonts
	fontLoader       FontLoader                // used to load font files from arbitrary locations
	coreFonts        map[string]bool           // array of core font names
	fonts            map[string]fontDefType    // array of used fonts
	fontFiles        map[string]fontFileType   // array of font files
	diffs            []string                  // array of encoding differences
	fontFamily       string                    // current font family
	fontStyle        string                    // current font style
	underline        bool                      // underlining flag
	currentFont      fontDefType               // current font info
	fontSizePt       float64                   // current font size in points
	fontSize         float64                   // current font size in user unit
	ws               float64                   // word spacing
	images           map[string]*ImageInfoType // array of used images
	pageLinks        [][]linkType              // pageLinks[page][link], both 1-based
	links            []intLinkType             // array of internal links
	outlines         []outlineType             // array of outlines
	outlineRoot      int                       // root of outlines
	autoPageBreak    bool                      // automatic page breaking
	acceptPageBreak  func() bool               // returns true to accept page break
	pageBreakTrigger float64                   // threshold used to trigger page breaks
	inHeader         bool                      // flag set when processing header
	headerFnc        func()                    // function provided by app and called to write header
	inFooter         bool                      // flag set when processing footer
	footerFnc        func()                    // function provided by app and called to write footer
	footerFncLpi     func(bool)                // function provided by app and called to write footer with last page flag
	zoomMode         string                    // zoom display mode
	layoutMode       string                    // layout display mode
	xmp              []byte                    // XMP metadata
	title            string                    // title
	subject          string                    // subject
	author           string                    // author
	keywords         string                    // keywords
	creator          string                    // creator
	creationDate     time.Time                 // override for dcoument CreationDate value
	aliasNbPagesStr  string                    // alias for total number of pages
	pdfVersion       string                    // PDF version number
	fontDirStr       string                    // location of font definition files
	capStyle         int                       // line cap style: butt 0, round 1, square 2
	joinStyle        int                       // line segment join style: miter 0, round 1, bevel 2
	dashArray        []float64                 // dash array
	dashPhase        float64                   // dash phase
	blendList        []blendModeType           // slice[idx] of alpha transparency modes, 1-based
	blendMap         map[string]int            // map into blendList
	blendMode        string                    // current blend mode
	alpha            float64                   // current transpacency
	gradientList     []gradientType            // slice[idx] of gradient records
	clipNest         int                       // Number of active clipping contexts
	transformNest    int                       // Number of active transformation contexts
	err              error                     // Set if error occurs during life cycle of instance
	protect          protectType               // document protection structure
	layer            layerRecType              // manages optional layers in document
	catalogSort      bool                      // sort resource catalogs in document
	nJs              int                       // JavaScript object number
	javascript       *string                   // JavaScript code to include in the PDF
	colorFlag        bool                      // indicates whether fill and text colors are different
	color            struct {
		// Composite values of colors
		draw, fill, text colorType
	}
	spotColorMap map[string]spotColorType // Map of named ink-based colors
}

これらを変更していくことでPDFを構成する。

Fpdf.SetHeaderFunc() - ヘッダーを設定する

	pdf.SetHeaderFunc(func() {
		pdf.SetY(5)
		pdf.SetFont("Arial", "B", 15)
		pdf.Cell(60, 0, "")
		pdf.CellFormat(
			80, 10, titleStr, "1", 0, "C", false, 0,
			"https://qiita.com/advent-calendar/2017/go2")
		pdf.Ln(20)
	})
simple.go

ヘッダーの設定はヘッダーを生成する関数を登録することで実現する。

Fpdf.SetFooterFunc() - フッターを設定する

	pdf.SetFooterFunc(func() {
		pdf.SetY(-15)
		pdf.SetFont("Arial", "I", 8)
		pdf.CellFormat(0, 10, fmt.Sprintf("Page %d/{nb}", pdf.PageNo()),
			"", 0, "C", false, 0, "")
	})
	pdf.AliasNbPages("")

フッターもヘッダー同様、フッターを生成する関数を登録することで実現する。

Fpdf.SetTitle() - タイトルを設定する

	pdf.SetTitle(titleStr, false)

第1引数は文字列、第二引数はUTF8とかどうかをboolで指定する。

Fpdf.SetAuthor() - Authorを設定する

	pdf.SetAuthor("TakesxiSximada", false)

第1引数は文字列、第二引数はUTF8とかどうかをboolで指定する。

Fpdf.SetFont() - フォントの設定

	pdf.SetFont("Arial", "B", 16)

フォントファミリー、スタイル、サイズを指定する。

Fpdf.AddPage() - ページを追加する

	pdf.AddPage()

Fpdf.Image() - 画像を追加する

	pdf.Image("./sximada.jpg", 160, 28, 30, 0, false, "", 0,
		"https://twitter.com/TakesxiSximada")

最後に渡しているURLはリンクのジャンプ先になる。

Fpdf.CellFormat() - Cellの情報を詳細に設定する

		pdf.CellFormat(width, 10, text, "", 0, "C", false, 0, "")

Fpdf.Cell()でセルを追加したが、それ以外の属性を指定したい場合は CellFormat()を使う。Fpdf.Cell()はCellFormat()を内部で呼び出している。

Fpdf.Ln() - 改行

		pdf.Ln(10)

Fpdf.SetProtection() - 制約を付与する

	pdf.SetProtection(gofpdf.CnProtectAnnotForms, "foo", "bar")

第一引数はフラグで次の値を指定できる。

意味
CnProtectPrint 印刷可能
CnProtectModify 編集可能
CnProtectCopy コピー可能
CnProtectAnnotForms アノテーションやフォームをPDFエディタで追加
// Advisory bitflag constants that control document activities
const (
	CnProtectPrint      = 4
	CnProtectModify     = 8
	CnProtectCopy       = 16
	CnProtectAnnotForms = 32
)

第2引数はユーザーパスワード。この値を設定するとファイルを開く場合にパ スワードを求める。第3引数はオーナーパスワード。ユーザーパスワードとの 違いは、このパスワードで開いた場合はこのPDFに対する全ての操作権限が与 えられる。

Fpdf.SetMargins() - マージンを設定する

	pdf.SetMargins(100, 100, 100)

Fpdf.Rect() - 四角を描画する

	pdf.Rect(3, 3, 3, 3, "F")

X、Y、幅、高さ、スタイルを指定する。例の場合では小さく黒い四角が左上に 出力される。

備考

この記事はGo2 Advent Calendar 2017及びしむどん Advent Calendar 2017の 19日目の記事として投稿されたもの。また元々は https://qiita.com/TakesxiSximada/items/58403d7e460db691093bに掲載した 記事の転載したものである。