This commit is contained in:
Mrx
2026-03-13 18:07:24 +08:00
parent f16274d1e9
commit 209ffec51d
16 changed files with 309 additions and 1176 deletions

View File

@@ -2078,69 +2078,55 @@ func (g *PDFGenerator) addHeader(pdf *gofpdf.Fpdf, chineseFontAvailable bool) {
pdf.Line(15, 22, 75, 22)
}
// addWatermark 添加水印(从左边开始向上倾斜45度,考虑可用区域)
// addWatermark 添加水印:自左下角往右上角倾斜 45°,单条水印居中于页面,样式柔和
func (g *PDFGenerator) addWatermark(pdf *gofpdf.Fpdf, chineseFontAvailable bool) {
// 如果中文字体不可用,跳过水印(避免显示乱码)
if !chineseFontAvailable {
return
}
// 保存当前图形状态
pdf.TransformBegin()
defer pdf.TransformEnd()
// 获取页面尺寸和边距
_, pageHeight := pdf.GetPageSize()
pageWidth, pageHeight := pdf.GetPageSize()
leftMargin, topMargin, _, bottomMargin := pdf.GetMargins()
// 计算实际可用区域高度
usableHeight := pageHeight - topMargin - bottomMargin
usableWidth := pageWidth - leftMargin*2
// 设置水印样式(使用中文字体)
fontSize := 45.0
fontSize := 42.0
pdf.SetFont("ChineseFont", "", fontSize)
// 设置灰色和透明度(加深水印,使其更明显)
pdf.SetTextColor(180, 180, 180) // 深一点的灰色
pdf.SetAlpha(0.25, "Normal") // 增加透明度,让水印更明显
pdf.SetTextColor(150, 150, 150)
pdf.SetAlpha(0.32, "Normal")
// 计算文字宽度
textWidth := pdf.GetStringWidth(g.watermarkText)
if textWidth == 0 {
// 如果无法获取宽度(字体未注册),使用估算值(中文字符大约每个 fontSize/3 mm
textWidth = float64(len([]rune(g.watermarkText))) * fontSize / 3.0
}
// 从左边开始,计算起始位置
// 起始X左边距
// 起始Y考虑水印文字长度和旋转后需要的空间
startX := leftMargin
startY := topMargin + textWidth*0.5 // 为旋转留出空间
// 移动到起始位置
pdf.TransformTranslate(startX, startY)
// 向上倾斜45度顺时针旋转45度即-45度或逆时针315度
pdf.TransformRotate(-45, 0, 0)
// 检查文字是否会超出可用区域(旋转后的对角线长度)
rotatedDiagonal := math.Sqrt(textWidth*textWidth + fontSize*fontSize)
if rotatedDiagonal > usableHeight*0.8 {
// 如果太大,缩小字体
fontSize = fontSize * usableHeight * 0.8 / rotatedDiagonal
if rotatedDiagonal > usableHeight*0.75 {
fontSize = fontSize * usableHeight * 0.75 / rotatedDiagonal
pdf.SetFont("ChineseFont", "", fontSize)
textWidth = pdf.GetStringWidth(g.watermarkText)
if textWidth == 0 {
textWidth = float64(len([]rune(g.watermarkText))) * fontSize / 3.0
}
rotatedDiagonal = math.Sqrt(textWidth*textWidth + fontSize*fontSize)
}
// 从左边开始绘制水印文字
startX := leftMargin
startY := pageHeight - bottomMargin
diagW := rotatedDiagonal * math.Cos(45*math.Pi/180)
offsetX := (usableWidth - diagW) * 0.5
startX += offsetX
startY -= rotatedDiagonal * 0.5
pdf.TransformTranslate(startX, startY)
pdf.TransformRotate(45, 0, 0)
pdf.SetXY(0, 0)
pdf.CellFormat(textWidth, fontSize, g.watermarkText, "", 0, "L", false, 0, "")
// 恢复透明度和颜色
pdf.SetAlpha(1.0, "Normal")
pdf.SetTextColor(0, 0, 0) // 恢复为黑色
pdf.SetTextColor(0, 0, 0)
}