package document
import (
"fmt"
)
// Table 表示Word文档中的表格
type Table struct {
Rows []*TableRow
Properties *TableProperties
}
// TableProperties 表示表格的属性
type TableProperties struct {
Width int // 表格宽度,单位为twip
WidthType string // 宽度类型:auto, dxa, pct
Alignment string // 对齐方式:left, center, right
Indent int // 缩进
Borders *TableBorders
CellMargin *TableCellMargin
Layout string // 布局方式:fixed, autofit
Look string // 表格外观
Style string // 表格样式ID
FirstRow bool // 首行特殊格式
LastRow bool // 末行特殊格式
FirstColumn bool // 首列特殊格式
LastColumn bool // 末列特殊格式
NoHBand bool // 无水平带状格式
NoVBand bool // 无垂直带状格式
}
// TableBorders 表示表格的边框
type TableBorders struct {
Top *Border
Bottom *Border
Left *Border
Right *Border
InsideH *Border
InsideV *Border
}
// TableCellMargin 表示表格单元格的边距
type TableCellMargin struct {
Top int
Bottom int
Left int
Right int
}
// TableRow 表示表格的行
type TableRow struct {
Cells []*TableCell
Properties *TableRowProperties
}
// TableRowProperties 表示表格行的属性
type TableRowProperties struct {
Height int // 行高,单位为twip
HeightRule string // 行高规则:atLeast, exact, auto
CantSplit bool // 不允许跨页分割
IsHeader bool // 是否为表头行
}
// TableCell 表示表格的单元格
type TableCell struct {
Content []interface{} // 可以是段落、表格等元素
Properties *TableCellProperties
}
// TableCellProperties 表示表格单元格的属性
type TableCellProperties struct {
Width int // 单元格宽度,单位为twip
WidthType string // 宽度类型:auto, dxa, pct
VertAlign string // 垂直对齐方式:top, center, bottom
Borders *TableBorders
Shading *Shading
GridSpan int // 跨列数
VMerge string // 垂直合并:restart, continue
NoWrap bool // 不换行
FitText bool // 适应文本
}
// NewTable 创建一个新的表格
func NewTable(rows, cols int) *Table {
t := &Table{
Rows: make([]*TableRow, 0),
Properties: &TableProperties{
Width: 0,
WidthType: "auto",
Alignment: "left",
Layout: "autofit",
Borders: &TableBorders{
Top: &Border{Style: "single", Size: 4, Color: "000000", Space: 0},
Bottom: &Border{Style: "single", Size: 4, Color: "000000", Space: 0},
Left: &Border{Style: "single", Size: 4, Color: "000000", Space: 0},
Right: &Border{Style: "single", Size: 4, Color: "000000", Space: 0},
InsideH: &Border{Style: "single", Size: 4, Color: "000000", Space: 0},
InsideV: &Border{Style: "single", Size: 4, Color: "000000", Space: 0},
},
CellMargin: &TableCellMargin{
Top: 0,
Bottom: 0,
Left: 108, // 约0.15厘米
Right: 108,
},
},
}
// 创建行和单元格
for i := 0; i < rows; i++ {
row := t.AddRow()
for j := 0; j < cols; j++ {
row.AddCell()
}
}
return t
}
// AddRow 向表格添加一行并返回它
func (t *Table) AddRow() *TableRow {
r := &TableRow{
Cells: make([]*TableCell, 0),
Properties: &TableRowProperties{
Height: 0,
HeightRule: "auto",
CantSplit: false,
IsHeader: false,
},
}
t.Rows = append(t.Rows, r)
return r
}
// SetWidth 设置表格宽度
func (t *Table) SetWidth(width int, widthType string) *Table {
t.Properties.Width = width
t.Properties.WidthType = widthType
return t
}
// SetAlignment 设置表格对齐方式
func (t *Table) SetAlignment(alignment string) *Table {
t.Properties.Alignment = alignment
return t
}
// SetIndent 设置表格缩进
func (t *Table) SetIndent(indent int) *Table {
t.Properties.Indent = indent
return t
}
// SetLayout 设置表格布局方式
func (t *Table) SetLayout(layout string) *Table {
t.Properties.Layout = layout
return t
}
// SetBorders 设置表格边框
func (t *Table) SetBorders(position string, style string, size int, color string) *Table {
border := &Border{
Style: style,
Size: size,
Color: color,
Space: 0,
}
switch position {
case "top":
t.Properties.Borders.Top = border
case "bottom":
t.Properties.Borders.Bottom = border
case "left":
t.Properties.Borders.Left = border
case "right":
t.Properties.Borders.Right = border
case "insideH":
t.Properties.Borders.InsideH = border
case "insideV":
t.Properties.Borders.InsideV = border
case "all":
t.Properties.Borders.Top = border
t.Properties.Borders.Bottom = border
t.Properties.Borders.Left = border
t.Properties.Borders.Right = border
t.Properties.Borders.InsideH = border
t.Properties.Borders.InsideV = border
}
return t
}
// SetCellMargin 设置表格单元格边距
func (t *Table) SetCellMargin(position string, margin int) *Table {
switch position {
case "top":
t.Properties.CellMargin.Top = margin
case "bottom":
t.Properties.CellMargin.Bottom = margin
case "left":
t.Properties.CellMargin.Left = margin
case "right":
t.Properties.CellMargin.Right = margin
case "all":
t.Properties.CellMargin.Top = margin
t.Properties.CellMargin.Bottom = margin
t.Properties.CellMargin.Left = margin
t.Properties.CellMargin.Right = margin
}
return t
}
// SetStyle 设置表格样式
func (t *Table) SetStyle(style string) *Table {
t.Properties.Style = style
return t
}
// SetLook 设置表格外观
func (t *Table) SetLook(firstRow, lastRow, firstColumn, lastColumn, noHBand, noVBand bool) *Table {
t.Properties.FirstRow = firstRow
t.Properties.LastRow = lastRow
t.Properties.FirstColumn = firstColumn
t.Properties.LastColumn = lastColumn
t.Properties.NoHBand = noHBand
t.Properties.NoVBand = noVBand
// 计算Look值
look := 0
if firstRow {
look |= 0x0020
}
if lastRow {
look |= 0x0040
}
if firstColumn {
look |= 0x0080
}
if lastColumn {
look |= 0x0100
}
if noHBand {
look |= 0x0200
}
if noVBand {
look |= 0x0400
}
t.Properties.Look = fmt.Sprintf("%04X", look)
return t
}
// AddCell 向表格行添加一个单元格并返回它
func (r *TableRow) AddCell() *TableCell {
c := &TableCell{
Content: make([]interface{}, 0),
Properties: &TableCellProperties{
Width: 0,
WidthType: "auto",
VertAlign: "top",
GridSpan: 1,
},
}
r.Cells = append(r.Cells, c)
return c
}
// SetHeight 设置行高
func (r *TableRow) SetHeight(height int, rule string) *TableRow {
r.Properties.Height = height
r.Properties.HeightRule = rule
return r
}
// SetCantSplit 设置不允许跨页分割
func (r *TableRow) SetCantSplit(cantSplit bool) *TableRow {
r.Properties.CantSplit = cantSplit
return r
}
// SetIsHeader 设置是否为表头行
func (r *TableRow) SetIsHeader(isHeader bool) *TableRow {
r.Properties.IsHeader = isHeader
return r
}
// AddParagraph 向单元格添加一个段落并返回它
func (c *TableCell) AddParagraph() *Paragraph {
p := NewParagraph()
c.Content = append(c.Content, p)
return p
}
// AddTable 向单元格添加一个表格并返回它
func (c *TableCell) AddTable(rows, cols int) *Table {
t := NewTable(rows, cols)
c.Content = append(c.Content, t)
return t
}
// SetWidth 设置单元格宽度
func (c *TableCell) SetWidth(width int, widthType string) *TableCell {
c.Properties.Width = width
c.Properties.WidthType = widthType
return c
}
// SetVertAlign 设置单元格垂直对齐方式
func (c *TableCell) SetVertAlign(vertAlign string) *TableCell {
c.Properties.VertAlign = vertAlign
return c
}
// SetBorders 设置单元格边框
func (c *TableCell) SetBorders(position string, style string, size int, color string) *TableCell {
if c.Properties.Borders == nil {
c.Properties.Borders = &TableBorders{}
}
border := &Border{
Style: style,
Size: size,
Color: color,
Space: 0,
}
switch position {
case "top":
c.Properties.Borders.Top = border
case "bottom":
c.Properties.Borders.Bottom = border
case "left":
c.Properties.Borders.Left = border
case "right":
c.Properties.Borders.Right = border
case "all":
c.Properties.Borders.Top = border
c.Properties.Borders.Bottom = border
c.Properties.Borders.Left = border
c.Properties.Borders.Right = border
}
return c
}
// SetShading 设置单元格底纹
func (c *TableCell) SetShading(fill, color, pattern string) *TableCell {
c.Properties.Shading = &Shading{
Fill: fill,
Color: color,
Pattern: pattern,
}
return c
}
// SetGridSpan 设置单元格跨列数
func (c *TableCell) SetGridSpan(gridSpan int) *TableCell {
c.Properties.GridSpan = gridSpan
return c
}
// SetVMerge 设置单元格垂直合并
func (c *TableCell) SetVMerge(vMerge string) *TableCell {
c.Properties.VMerge = vMerge
return c
}
// SetNoWrap 设置单元格不换行
func (c *TableCell) SetNoWrap(noWrap bool) *TableCell {
c.Properties.NoWrap = noWrap
return c
}
// SetFitText 设置单元格适应文本
func (c *TableCell) SetFitText(fitText bool) *TableCell {
c.Properties.FitText = fitText
return c
}
// ToXML 将表格转换为XML
func (t *Table) ToXML() string {
xml := ""
// 添加表格属性
xml += ""
// 表格样式ID
if t.Properties.Style != "" {
xml += fmt.Sprintf("", t.Properties.Style)
}
// 表格宽度
xml += fmt.Sprintf("", t.Properties.Width, t.Properties.WidthType)
// 表格对齐方式
if t.Properties.Alignment != "" {
xml += fmt.Sprintf("", t.Properties.Alignment)
}
// 表格缩进
if t.Properties.Indent > 0 {
xml += fmt.Sprintf("", t.Properties.Indent)
}
// 表格边框
if t.Properties.Borders != nil {
xml += ""
if t.Properties.Borders.Top != nil {
xml += fmt.Sprintf("",
t.Properties.Borders.Top.Style,
t.Properties.Borders.Top.Size,
t.Properties.Borders.Top.Space,
t.Properties.Borders.Top.Color)
}
if t.Properties.Borders.Left != nil {
xml += fmt.Sprintf("",
t.Properties.Borders.Left.Style,
t.Properties.Borders.Left.Size,
t.Properties.Borders.Left.Space,
t.Properties.Borders.Left.Color)
}
if t.Properties.Borders.Bottom != nil {
xml += fmt.Sprintf("",
t.Properties.Borders.Bottom.Style,
t.Properties.Borders.Bottom.Size,
t.Properties.Borders.Bottom.Space,
t.Properties.Borders.Bottom.Color)
}
if t.Properties.Borders.Right != nil {
xml += fmt.Sprintf("",
t.Properties.Borders.Right.Style,
t.Properties.Borders.Right.Size,
t.Properties.Borders.Right.Space,
t.Properties.Borders.Right.Color)
}
if t.Properties.Borders.InsideH != nil {
xml += fmt.Sprintf("",
t.Properties.Borders.InsideH.Style,
t.Properties.Borders.InsideH.Size,
t.Properties.Borders.InsideH.Space,
t.Properties.Borders.InsideH.Color)
}
if t.Properties.Borders.InsideV != nil {
xml += fmt.Sprintf("",
t.Properties.Borders.InsideV.Style,
t.Properties.Borders.InsideV.Size,
t.Properties.Borders.InsideV.Space,
t.Properties.Borders.InsideV.Color)
}
xml += ""
}
// 表格布局
if t.Properties.Layout != "" {
xml += fmt.Sprintf("", t.Properties.Layout)
}
// 单元格边距
if t.Properties.CellMargin != nil {
xml += ""
if t.Properties.CellMargin.Top > 0 {
xml += fmt.Sprintf("", t.Properties.CellMargin.Top)
}
if t.Properties.CellMargin.Left > 0 {
xml += fmt.Sprintf("", t.Properties.CellMargin.Left)
}
if t.Properties.CellMargin.Bottom > 0 {
xml += fmt.Sprintf("", t.Properties.CellMargin.Bottom)
}
if t.Properties.CellMargin.Right > 0 {
xml += fmt.Sprintf("", t.Properties.CellMargin.Right)
}
xml += ""
}
// 表格外观
if t.Properties.Look != "" {
xml += fmt.Sprintf("",
t.Properties.Look,
formatBoolToWXml(t.Properties.FirstRow),
formatBoolToWXml(t.Properties.LastRow),
formatBoolToWXml(t.Properties.FirstColumn),
formatBoolToWXml(t.Properties.LastColumn),
formatBoolToWXml(t.Properties.NoHBand),
formatBoolToWXml(t.Properties.NoVBand))
}
xml += ""
// 添加表格网格
xml += ""
if len(t.Rows) > 0 && len(t.Rows[0].Cells) > 0 {
for i := 0; i < len(t.Rows[0].Cells); i++ {
xml += ""
}
}
xml += ""
// 添加所有行的XML
for _, row := range t.Rows {
xml += row.ToXML()
}
xml += ""
return xml
}
// formatBoolToWXml 将布尔值转换为Word XML中使用的字符串表示
func formatBoolToWXml(value bool) string {
if value {
return "1"
}
return "0"
}
// ToXML 将表格行转换为XML
func (r *TableRow) ToXML() string {
xml := ""
// 添加行属性
xml += ""
// 行高
if r.Properties.Height > 0 {
xml += ""
}
// 不允许跨页分割
if r.Properties.CantSplit {
xml += ""
}
// 表头行
if r.Properties.IsHeader {
xml += ""
}
xml += ""
// 添加所有单元格的XML
for _, cell := range r.Cells {
xml += cell.ToXML()
}
xml += ""
return xml
}
// ToXML 将表格单元格转换为XML
func (c *TableCell) ToXML() string {
xml := ""
// 添加单元格属性
xml += ""
// 单元格宽度
if c.Properties.Width > 0 {
xml += ""
} else {
xml += ""
}
// 垂直对齐方式
if c.Properties.VertAlign != "" {
xml += ""
}
// 单元格边框
if c.Properties.Borders != nil {
xml += ""
if c.Properties.Borders.Top != nil {
xml += ""
}
if c.Properties.Borders.Bottom != nil {
xml += ""
}
if c.Properties.Borders.Left != nil {
xml += ""
}
if c.Properties.Borders.Right != nil {
xml += ""
}
xml += ""
}
// 底纹
if c.Properties.Shading != nil {
xml += ""
}
// 跨列数
if c.Properties.GridSpan > 1 {
xml += ""
}
// 垂直合并
if c.Properties.VMerge != "" {
xml += ""
}
// 不换行
if c.Properties.NoWrap {
xml += ""
}
// 适应文本
if c.Properties.FitText {
xml += ""
}
xml += ""
// 添加所有内容元素的XML
for _, content := range c.Content {
switch v := content.(type) {
case *Paragraph:
xml += v.ToXML()
case *Table:
xml += v.ToXML()
}
}
// 如果单元格没有内容,添加一个空段落
if len(c.Content) == 0 {
xml += ""
}
xml += ""
return xml
}