この記事は Go2 Advent Calendar 2017 及び しむどん Advent Calendar 2017 の19日目の記事です。
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を生成します。
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()はページを追加します。追加したページが編集対象のページになります。
あ、デバッグコードがコメントアウトされて残っているw
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)
})
ヘッダーの設定はヘッダーを生成する関数を登録することで実現します。
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、幅、高さ、スタイルを指定します。例の場合では小さく黒い四角が左上に出力されます。