row span summary
This commit is contained in:
parent
4c054b3215
commit
17bf4aaf99
89
table.go
89
table.go
|
|
@ -116,12 +116,21 @@ func NewTableGenerator(config *TableConfig) *TableGenerator {
|
|||
|
||||
func (t *TableData) Check() error {
|
||||
headerLen := len(t.Headers)
|
||||
if headerLen <= 2 {
|
||||
for _, row := range t.Rows {
|
||||
if headerLen != len(row) {
|
||||
return fmt.Errorf("header length does not match row length")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for _, row := range t.Rows {
|
||||
rowLen := len(row)
|
||||
if rowLen != headerLen && rowLen != 2 {
|
||||
return fmt.Errorf("header length does not match row length")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 应用缩放因子
|
||||
|
|
@ -150,6 +159,28 @@ func (g *TableGenerator) calculateColumnWidths(data *TableData) []float64 {
|
|||
|
||||
// 检查每行内容的宽度
|
||||
for _, row := range data.Rows {
|
||||
if len(row) == 2 && colCount > 2 {
|
||||
// 第一列占一列
|
||||
width, _ := g.dc.MeasureString(row[0])
|
||||
totalWidth := width + g.scaled(g.config.Padding)*2
|
||||
if totalWidth > colWidths[0] {
|
||||
colWidths[0] = math.Min(totalWidth, g.scaled(g.config.MaxColWidth))
|
||||
}
|
||||
// 第二列跨剩余所有列
|
||||
width, _ = g.dc.MeasureString(row[1])
|
||||
totalWidth = width + g.scaled(g.config.Padding)*2
|
||||
remainingWidth := 0.0
|
||||
for k := 1; k < colCount; k++ {
|
||||
remainingWidth += colWidths[k]
|
||||
}
|
||||
if totalWidth > remainingWidth {
|
||||
diff := totalWidth - remainingWidth
|
||||
perCol := diff / float64(colCount-1)
|
||||
for k := 1; k < colCount; k++ {
|
||||
colWidths[k] += perCol
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for j, cell := range row {
|
||||
width, _ := g.dc.MeasureString(cell)
|
||||
totalWidth := width + g.scaled(g.config.Padding)*2
|
||||
|
|
@ -158,6 +189,7 @@ func (g *TableGenerator) calculateColumnWidths(data *TableData) []float64 {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return colWidths
|
||||
}
|
||||
|
|
@ -174,6 +206,25 @@ func (g *TableGenerator) calculateRowHeights(data *TableData, colWidths []float6
|
|||
// 计算每行内容的高度
|
||||
for i, row := range data.Rows {
|
||||
maxHeight := 0.0
|
||||
if len(row) == 2 && len(data.Headers) > 2 {
|
||||
// 第一列占一列
|
||||
lines := g.wrapText(row[0], colWidths[0]-g.scaled(g.config.Padding)*2)
|
||||
lineHeight := g.getLineHeight()
|
||||
cellHeight := float64(len(lines))*lineHeight + g.scaled(g.config.Padding)*2
|
||||
if cellHeight > maxHeight {
|
||||
maxHeight = cellHeight
|
||||
}
|
||||
// 第二列跨剩余所有列
|
||||
remainingWidth := 0.0
|
||||
for k := 1; k < len(colWidths); k++ {
|
||||
remainingWidth += colWidths[k]
|
||||
}
|
||||
lines = g.wrapText(row[1], remainingWidth-g.scaled(g.config.Padding)*2)
|
||||
cellHeight = float64(len(lines))*lineHeight + g.scaled(g.config.Padding)*2
|
||||
if cellHeight > maxHeight {
|
||||
maxHeight = cellHeight
|
||||
}
|
||||
} else {
|
||||
for j, cell := range row {
|
||||
// 测量文本在限定宽度内的高度
|
||||
lines := g.wrapText(cell, colWidths[j]-g.scaled(g.config.Padding)*2)
|
||||
|
|
@ -183,6 +234,7 @@ func (g *TableGenerator) calculateRowHeights(data *TableData, colWidths []float6
|
|||
maxHeight = cellHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
rowHeights[i+1] = maxHeight
|
||||
}
|
||||
|
||||
|
|
@ -354,8 +406,19 @@ func (g *TableGenerator) Generate(data *TableData, filename string) error {
|
|||
currentX := margin
|
||||
rowHeight := rowHeights[i]
|
||||
|
||||
isTwoColRow := i > 0 && len(data.Rows[i-1]) == 2 && len(data.Headers) > 2
|
||||
|
||||
for j := 0; j < len(colWidths); j++ {
|
||||
if isTwoColRow && j >= 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
colWidth := colWidths[j]
|
||||
if isTwoColRow && j == 1 {
|
||||
for k := 2; k < len(colWidths); k++ {
|
||||
colWidth += colWidths[k]
|
||||
}
|
||||
}
|
||||
|
||||
// 设置单元格背景色
|
||||
if i == 0 {
|
||||
|
|
@ -373,8 +436,16 @@ func (g *TableGenerator) Generate(data *TableData, filename string) error {
|
|||
if i == 0 {
|
||||
cellText = data.Headers[j]
|
||||
dc.SetColor(g.config.HeaderTextColor)
|
||||
} else {
|
||||
if isTwoColRow {
|
||||
if j == 0 {
|
||||
cellText = data.Rows[i-1][0]
|
||||
} else {
|
||||
cellText = data.Rows[i-1][1]
|
||||
}
|
||||
} else {
|
||||
cellText = data.Rows[i-1][j]
|
||||
}
|
||||
dc.SetColor(g.config.TextColor)
|
||||
}
|
||||
|
||||
|
|
@ -399,7 +470,7 @@ func (g *TableGenerator) Generate(data *TableData, filename string) error {
|
|||
}
|
||||
|
||||
// 绘制网格线(使用缩放后的线宽)
|
||||
g.drawGridLines(dc, colWidths, rowHeights, margin, tableStartY, tableWidth, tableHeight)
|
||||
g.drawGridLines(dc, colWidths, rowHeights, margin, tableStartY, tableWidth, tableHeight, data)
|
||||
|
||||
// 绘制外边框(使用缩放后的边框宽度)
|
||||
g.drawOuterBorder(dc, margin, tableStartY, tableWidth, tableHeight)
|
||||
|
|
@ -408,7 +479,7 @@ func (g *TableGenerator) Generate(data *TableData, filename string) error {
|
|||
}
|
||||
|
||||
// 绘制网格线(高清优化)
|
||||
func (g *TableGenerator) drawGridLines(dc *gg.Context, colWidths, rowHeights []float64, margin, startY, tableWidth, tableHeight float64) {
|
||||
func (g *TableGenerator) drawGridLines(dc *gg.Context, colWidths, rowHeights []float64, margin, startY, tableWidth, tableHeight float64, data *TableData) {
|
||||
dc.SetColor(g.config.LineColor)
|
||||
dc.SetLineWidth(g.scaled(g.config.LineWidth))
|
||||
|
||||
|
|
@ -425,8 +496,22 @@ func (g *TableGenerator) drawGridLines(dc *gg.Context, colWidths, rowHeights []f
|
|||
// 绘制垂直线
|
||||
currentX := margin
|
||||
for j := 0; j <= len(colWidths); j++ {
|
||||
if j == 0 || j == len(colWidths) || len(data.Headers) <= 2 {
|
||||
// 最左/最右的线直接画到底,或者列数<=2时不需要跳过
|
||||
dc.DrawLine(currentX, startY, currentX, startY+tableHeight)
|
||||
dc.Stroke()
|
||||
} else {
|
||||
// 内部垂直线,需要跳过2列合并行的内部
|
||||
currentY2 := startY
|
||||
for i := 0; i < len(rowHeights); i++ {
|
||||
isTwoColRow := i > 0 && len(data.Rows[i-1]) == 2 && len(data.Headers) > 2
|
||||
if !(isTwoColRow && j >= 2) {
|
||||
dc.DrawLine(currentX, currentY2, currentX, currentY2+rowHeights[i])
|
||||
dc.Stroke()
|
||||
}
|
||||
currentY2 += rowHeights[i]
|
||||
}
|
||||
}
|
||||
if j < len(colWidths) {
|
||||
currentX += colWidths[j]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue