package pdf_service import ( "bytes" "evening_detective/internal/models" "strings" "github.com/signintech/gopdf" "github.com/skip2/go-qrcode" ) func CreateTeamsPdf(teams []*models.Team) ([]byte, error) { pdf := &gopdf.GoPdf{} pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4}) // W: 595, H: 842 if err := pdf.AddTTFFont("main", "JetBrainsMono-Medium.ttf"); err != nil { return nil, err } if err := pdf.SetFont("main", "", 10); err != nil { return nil, err } padding := 17. xDelta := 187. yDelta := 202. for i, team := range teams { if i%12 == 0 { pdf.AddPage() pdf.SetPage(1 + i/12) } y := (padding + 15) + yDelta*float64(i%12/3) x := padding + xDelta*float64(i%3) url, err := team.GetTeamUrl() if err != nil { return nil, err } if err := printQR(pdf, url, x+21, y); err != nil { return nil, err } if err := printTextCenter(pdf, team.Name, xDelta-6, x+3, 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 }