This commit is contained in:
@@ -270,25 +270,31 @@ func (r *DatabaseTableRenderer) safeSplitText(pdf *gofpdf.Fpdf, text string, wid
|
||||
|
||||
// 如果文本为空或宽度无效,返回单行
|
||||
if text == "" || width <= 0 {
|
||||
if text == "" {
|
||||
return []string{""}
|
||||
}
|
||||
return []string{text}
|
||||
}
|
||||
|
||||
// 检查文本长度,如果太短可能不需要分割
|
||||
if len([]rune(text)) <= 1 {
|
||||
return []string{text}
|
||||
}
|
||||
|
||||
// 使用匿名函数和recover保护SplitText调用
|
||||
var lines []string
|
||||
var panicOccurred bool
|
||||
func() {
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
r.logger.Warn("SplitText发生panic,使用估算值",
|
||||
zap.Any("error", rec),
|
||||
zap.String("text_preview", func() string {
|
||||
if len(text) > 50 {
|
||||
return text[:50] + "..."
|
||||
}
|
||||
return text
|
||||
}()),
|
||||
zap.Float64("width", width))
|
||||
panicOccurred = true
|
||||
// 静默处理,不记录日志
|
||||
// 如果panic发生,使用估算值
|
||||
charCount := len([]rune(text))
|
||||
if charCount == 0 {
|
||||
lines = []string{""}
|
||||
return
|
||||
}
|
||||
estimatedLines := math.Max(1, math.Ceil(float64(charCount)/20))
|
||||
lines = make([]string, int(estimatedLines))
|
||||
if estimatedLines == 1 {
|
||||
@@ -316,12 +322,27 @@ func (r *DatabaseTableRenderer) safeSplitText(pdf *gofpdf.Fpdf, text string, wid
|
||||
lines = pdf.SplitText(text, width)
|
||||
}()
|
||||
|
||||
// 如果lines为nil或空,返回单行
|
||||
if lines == nil || len(lines) == 0 {
|
||||
// 如果panic发生或lines为nil或空,使用后备方案
|
||||
if panicOccurred || lines == nil || len(lines) == 0 {
|
||||
// 如果文本不为空,至少返回一行
|
||||
if text != "" {
|
||||
return []string{text}
|
||||
}
|
||||
return []string{""}
|
||||
}
|
||||
|
||||
// 过滤掉空行(但保留至少一行)
|
||||
nonEmptyLines := make([]string, 0, len(lines))
|
||||
for _, line := range lines {
|
||||
if strings.TrimSpace(line) != "" {
|
||||
nonEmptyLines = append(nonEmptyLines, line)
|
||||
}
|
||||
}
|
||||
if len(nonEmptyLines) == 0 {
|
||||
return []string{text}
|
||||
}
|
||||
|
||||
return lines
|
||||
return nonEmptyLines
|
||||
}
|
||||
|
||||
// renderHeader 渲染表头
|
||||
@@ -450,6 +471,10 @@ func (r *DatabaseTableRenderer) renderRows(pdf *gofpdf.Fpdf, rows [][]string, co
|
||||
validRowIndex++
|
||||
|
||||
// 计算这一行的最大高度
|
||||
// 确保lineHt有效
|
||||
if lineHt <= 0 {
|
||||
lineHt = 5.0 // 默认行高
|
||||
}
|
||||
maxCellHeight := lineHt * 2.0 // 使用合理的最小高度
|
||||
for j := 0; j < numCols && j < len(row); j++ {
|
||||
cell := row[j]
|
||||
@@ -471,12 +496,32 @@ func (r *DatabaseTableRenderer) renderRows(pdf *gofpdf.Fpdf, rows [][]string, co
|
||||
lines = []string{cell}
|
||||
}
|
||||
|
||||
cellHeight := float64(len(lines)) * lineHt
|
||||
// 确保lines不为空且有效
|
||||
if len(lines) == 0 || (len(lines) == 1 && lines[0] == "") {
|
||||
lines = []string{cell}
|
||||
if lines[0] == "" {
|
||||
lines[0] = " " // 至少保留一个空格,避免高度为0
|
||||
}
|
||||
}
|
||||
|
||||
// 计算单元格高度,确保不会出现Inf或NaN
|
||||
lineCount := float64(len(lines))
|
||||
if lineCount <= 0 {
|
||||
lineCount = 1
|
||||
}
|
||||
if lineHt <= 0 {
|
||||
lineHt = 5.0 // 默认行高
|
||||
}
|
||||
cellHeight := lineCount * lineHt
|
||||
// 添加上下内边距
|
||||
cellHeight += lineHt * 0.8 // 上下各0.4倍行高的内边距
|
||||
if cellHeight < lineHt*2.0 {
|
||||
cellHeight = lineHt * 2.0
|
||||
}
|
||||
// 检查是否为有效数值
|
||||
if math.IsInf(cellHeight, 0) || math.IsNaN(cellHeight) {
|
||||
cellHeight = lineHt * 2.0
|
||||
}
|
||||
if cellHeight > maxCellHeight {
|
||||
maxCellHeight = cellHeight
|
||||
}
|
||||
@@ -545,10 +590,7 @@ func (r *DatabaseTableRenderer) renderRows(pdf *gofpdf.Fpdf, rows [][]string, co
|
||||
func() {
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
r.logger.Warn("MultiCell渲染失败",
|
||||
zap.Any("error", rec),
|
||||
zap.Int("row_index", rowIndex),
|
||||
zap.Int("col_index", j))
|
||||
// 静默处理,不记录日志
|
||||
}
|
||||
}()
|
||||
// 使用正常的行高,文本已经垂直居中
|
||||
@@ -561,8 +603,20 @@ func (r *DatabaseTableRenderer) renderRows(pdf *gofpdf.Fpdf, rows [][]string, co
|
||||
currentX += colW
|
||||
}
|
||||
|
||||
// 检查maxCellHeight是否为有效数值
|
||||
if math.IsInf(maxCellHeight, 0) || math.IsNaN(maxCellHeight) {
|
||||
maxCellHeight = lineHt * 2.0
|
||||
}
|
||||
if maxCellHeight <= 0 {
|
||||
maxCellHeight = lineHt * 2.0
|
||||
}
|
||||
|
||||
// 移动到下一行
|
||||
pdf.SetXY(15.0, startY+maxCellHeight)
|
||||
nextY := startY + maxCellHeight
|
||||
if math.IsInf(nextY, 0) || math.IsNaN(nextY) {
|
||||
nextY = pdf.GetY() + lineHt*2.0
|
||||
}
|
||||
pdf.SetXY(15.0, nextY)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user