はじめに
こちらのページの記事が面白かった
DBのレコード拾ってPDFの文言変えて遊んでみたので備忘録
test DBに下記のようなusersテーブルを作っておく
+------+--------+--------+------------+
| id | name | price | date |
+------+--------+--------+------------+
| 0001 | hoge | 1000 | 2023-06-01 |
| 0002 | huga | 2000 | 2023-07-01 |
| 0003 | wawawa | 500 | 2023-08-01 |
| 0004 | aheahe | 999 | 2023-06-30 |
| 0005 | aaa | 100000 | 2023-07-31 |
+------+--------+--------+------------+
コード
こんな感じ
test.go
package main
import (
"database/sql"
"fmt"
"strings"
"regexp"
"github.com/dustin/go-humanize"
"github.com/signintech/gopdf"
_ "github.com/go-sql-driver/mysql"
)
//レコード格納用の構造体
var (
id string
name string
price int
date string
)
func main() {
//ログイン情報取得
var n string
fmt.Println("DBのユーザ名を入力してください")
fmt.Scan(&n)
var m string
fmt.Println("パスワードを入力してください")
fmt.Scan(&m)
//ログイン情報生成
con := n + ":" + m + "@tcp(127.0.0.1:3306)/test"
//検査
db, err := sql.Open("mysql", con)
defer db.Close()
//設定誤りあれば出力
if err != nil {
fmt.Println("設定誤りを検知しました 下記参照し管理者に問い合わせてください")
fmt.Println(err.Error())
}
//DB応答確認
err = db.Ping()
if err != nil {
fmt.Println("ユーザ名かパスワードが間違っています")
return
} else {
//成功したら入力を受け付け
var n string
fmt.Println("IDを入力してください")
fmt.Scan(&n)
//インジェクション対策(のつもり)
if regexp.MustCompile(`^[0-9]{4}$`).MatchString(n) == false {
fmt.Println("不正な入力値です")
return
}
//入力値からクエリ生成
sql, err := db.Query("SELECT * FROM users WHERE id = '" + n + "'")
if err != nil {
fmt.Println(err.Error())
return
}
defer sql.Close()
//各レコードを格納(と言っても1つしか出てこないけど)
for sql.Next() {
err = sql.Scan(&id, &name, &price, &date)
if err != nil {
panic(err.Error())
}
}
//金額をカンマ区切りにする
price := humanize.Comma(int64(price))
//日付をハイフンで分割
date := strings.Split(date, "-")
//obj作成
pdf := gopdf.GoPdf{}
//サイズ指定
A4 := *gopdf.PageSizeA4
//横向き
A4Yoko := gopdf.Rect{W: A4.H, H: A4.W}
pdf.Start(gopdf.Config{PageSize: A4Yoko})
pdf.AddPage()
//インポート対象のファイルパス,ページ,PDFのボックス
template := pdf.ImportPage("./template.pdf", 1, "/MediaBox")
pageH := 1080 * (A4Yoko.W / 1920)
pdf.UseImportedTemplate(template, 0, 0, A4Yoko.W, pageH)
//ttfファイルを取込
err = pdf.AddTTFFont("ipaexg", "./ipaexg.ttf")
if err != nil {
panic(err)
}
//DBから取得した氏名、日付、金額を挿入
pdf.SetFont("ipaexg", "", 28)
drawText(&pdf, 300, 150, name)
pdf.SetFont("ipaexg", "", 15)
drawText(&pdf, 570, 100, date[0])
drawText(&pdf, 635, 100, date[1])
drawText(&pdf, 676, 100, date[2])
pdf.SetFont("ipaexg", "", 28)
drawText(&pdf, 280, 200, "¥ " + price + "-")
//IDでPDF命名すると誰宛の領収書かわかりやすい
pdf.WritePdf("/tmp/" + id + ".pdf")
fmt.Println(id + "の領収書を生成しました")
}
}
func drawText(pdf *gopdf.GoPdf, x float64, y float64, s string) {
pdf.SetX(x)
pdf.SetY(y)
pdf.Cell(nil, s)
}
コマンドラインからDBのユーザ名とパスワードとusersのID入れてクエリ叩いて結果を挿入する感じ
ID入力時に正規表現で引っかけてチェックしてるからクエリ実行時のエラーチェックはいらんかも
結果
うまいこと行ったっぽい
pdf.Cell()が文字列型しか扱えないのがちょっと不便かな
参考文献
https://news.mynavi.jp/techplus/article/gogogo-16/
https://www.chuken-engineer.com/entry/2021/09/24/162120#6%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8BSELECT
請求書ひな型
https://kujirahand.com/blog/index.php?%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8BGo%E8%A8%80%E8%AA%9E%E3%81%AE%E7%B4%A0%E6%9D%90