generated from VLADIMIR/template
clear pdf
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
package pdf
|
||||
|
||||
import "evening_detective/internal/models"
|
||||
|
||||
type IPDFGenerator interface {
|
||||
CreateTeamsPDF(teams []*models.Team) ([]byte, error)
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package pdf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"embed"
|
||||
"evening_detective/internal/models"
|
||||
"strings"
|
||||
|
||||
"github.com/signintech/gopdf"
|
||||
"github.com/skip2/go-qrcode"
|
||||
)
|
||||
|
||||
//go:embed JetBrainsMono-Medium.ttf
|
||||
var f embed.FS
|
||||
|
||||
type service struct{}
|
||||
|
||||
func NewPDFGenerator() IPDFGenerator {
|
||||
return &service{}
|
||||
}
|
||||
|
||||
func (s *service) CreateTeamsPDF(teams []*models.Team) ([]byte, error) {
|
||||
pdf := &gopdf.GoPdf{}
|
||||
pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4}) // W: 595, H: 842
|
||||
file, err := f.Open("JetBrainsMono-Medium.ttf")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := pdf.AddTTFFontByReader("main", file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := pdf.SetFont("main", "", 10); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
countOnPage := 9
|
||||
padding := 17.
|
||||
xDelta := 187.
|
||||
yDelta := 260.
|
||||
for i, team := range teams {
|
||||
if i%countOnPage == 0 {
|
||||
pdf.AddPage()
|
||||
pdf.SetPage(1 + i/countOnPage)
|
||||
}
|
||||
y := (padding + 15) + yDelta*float64(i%countOnPage/3)
|
||||
x := padding + xDelta*float64(i%3)
|
||||
|
||||
if err := printTextCenter(pdf, "Подключите Wi-Fi", xDelta-6, x+3, y); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := printTextCenter(pdf, "Имя: evening_detective", xDelta-6, x+3, 15+y); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := printTextCenter(pdf, "Пароль: 12345678", xDelta-6, x+3, 30+y); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := printQR(pdf, team.Link, x+21, 65+y); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := printTextCenter(pdf, "Войдите в приложение по qr", xDelta-6, x+3, 55+y); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := printTextCenter(pdf, team.Name, xDelta-6, x+3, 55+y+150); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
buffer := &bytes.Buffer{}
|
||||
_, err = pdf.WriteTo(buffer)
|
||||
return buffer.Bytes(), err
|
||||
}
|
||||
|
||||
func printQR(pdf *gopdf.GoPdf, url string, x, y float64) error {
|
||||
png, err := qrcode.Encode(url, qrcode.Medium, 256)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
imgHolder, err := gopdf.ImageHolderByBytes(png)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = pdf.ImageByHolder(imgHolder, x, y, &gopdf.Rect{W: 145, H: 145})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printTextCenter(pdf *gopdf.GoPdf, text string, pageWidth, x, y float64) error {
|
||||
lines := splitTextByWords(pdf, text, pageWidth)
|
||||
for i, line := range lines {
|
||||
lineWidth, err := pdf.MeasureTextWidth(line)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
xLine := x + (pageWidth-lineWidth)/2
|
||||
yLine := y + 15*float64(i)
|
||||
pdf.SetXY(xLine, yLine)
|
||||
|
||||
pdf.Cell(nil, line)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func splitTextByWords(pdf *gopdf.GoPdf, text string, maxWidth float64) []string {
|
||||
words := strings.Fields(text)
|
||||
var lines []string
|
||||
var currentLine string
|
||||
|
||||
for _, word := range words {
|
||||
testLine := currentLine
|
||||
if testLine != "" {
|
||||
testLine += " " + word
|
||||
} else {
|
||||
testLine = word
|
||||
}
|
||||
|
||||
width, _ := pdf.MeasureTextWidth(testLine)
|
||||
|
||||
if width <= maxWidth {
|
||||
currentLine = testLine
|
||||
} else {
|
||||
if currentLine != "" {
|
||||
lines = append(lines, currentLine)
|
||||
}
|
||||
currentLine = word
|
||||
}
|
||||
}
|
||||
|
||||
if currentLine != "" {
|
||||
lines = append(lines, currentLine)
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
||||
Reference in New Issue
Block a user