diff --git a/apitable.go b/apitable.go index c756cc8..0854d04 100644 --- a/apitable.go +++ b/apitable.go @@ -128,3 +128,37 @@ func (f *Docx) AddTableTwips(rowHeights []int64, colWidths []int64) *WTable { return *(**WTable)(unsafe.Add(unsafe.Pointer(&t), unsafe.Sizeof(uintptr(0)))) } + +// Justification allows to set table's horizonal alignment +// +// w:jc 属性的取值可以是以下之一: +// start:左对齐。 +// center:居中对齐。 +// end:右对齐。 +// both:两端对齐。 +// distribute:分散对齐。 +func (t *WTable) Justification(val string) *WTable { + if t.TableProperties.Justification == nil { + t.TableProperties.Justification = &Justification{Val: val} + return t + } + t.TableProperties.Justification.Val = val + return t +} + +// Justification allows to set table's horizonal alignment +// +// w:jc 属性的取值可以是以下之一: +// start:左对齐。 +// center:居中对齐。 +// end:右对齐。 +// both:两端对齐。 +// distribute:分散对齐。 +func (t *WTableRow) Justification(val string) *WTableRow { + if t.TableRowProperties.Justification == nil { + t.TableRowProperties.Justification = &Justification{Val: val} + return t + } + t.TableRowProperties.Justification.Val = val + return t +} diff --git a/cmd/main/main.go b/cmd/main/main.go index 4450840..9495cc3 100644 --- a/cmd/main/main.go +++ b/cmd/main/main.go @@ -97,9 +97,11 @@ func main() { w.AddParagraph() - tbl2 := w.AddTableTwips([]int64{2333, 2333, 2333}, []int64{2333, 2333}) + tbl2 := w.AddTableTwips([]int64{2333, 2333, 2333}, []int64{2333, 2333}).Justification("center") for x, r := range tbl2.TableRows { + r.Justification("center") for y, c := range r.TableCells { + c.TableCellProperties.VAlign = &docxlib.WVerticalAlignment{Val: "center"} c.AddParagraph().Justification("center").AddText(fmt.Sprintf("(%d, %d)", x, y)) } } diff --git a/structtable.go b/structtable.go index ab944d6..ea37179 100644 --- a/structtable.go +++ b/structtable.go @@ -84,11 +84,13 @@ func (t *WTable) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { // WTableProperties is an element that represents the properties of a table in Word document. type WTableProperties struct { - XMLName xml.Name `xml:"w:tblPr,omitempty"` - Style *WTableStyle - Width *WTableWidth - TableBorders *WTableBorders `xml:"w:tblBorders"` - Look *WTableLook + XMLName xml.Name `xml:"w:tblPr,omitempty"` + Position *WTablePositioningProperties + Style *WTableStyle + Width *WTableWidth + Justification *Justification `xml:"w:jc,omitempty"` + TableBorders *WTableBorders `xml:"w:tblBorders"` + Look *WTableLook } // UnmarshalXML implements the xml.Unmarshaler interface. @@ -103,6 +105,12 @@ func (t *WTableProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) } if tt, ok := token.(xml.StartElement); ok { switch tt.Name.Local { + case "tblpPr": + t.Position = new(WTablePositioningProperties) + err = d.DecodeElement(t.Position, &tt) + if err != nil && !strings.HasPrefix(err.Error(), "expected") { + return err + } case "tblStyle": t.Style = new(WTableStyle) err = d.DecodeElement(t.Style, &tt) @@ -115,6 +123,19 @@ func (t *WTableProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) if err != nil && !strings.HasPrefix(err.Error(), "expected") { return err } + case "jc": + th := new(Justification) + for _, attr := range tt.Attr { + if attr.Name.Local == "val" { + th.Val = attr.Value + break + } + } + t.Justification = th + err = d.Skip() + if err != nil { + return err + } case "tblLook": t.Look = new(WTableLook) err = d.DecodeElement(t.Look, &tt) @@ -139,6 +160,55 @@ func (t *WTableProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) return nil } +// WTablePositioningProperties is an element that contains the properties +// for positioning a table within a document page, including its horizontal +// and vertical anchors, distance from text, and coordinates. +type WTablePositioningProperties struct { + XMLName xml.Name `xml:"w:tblpPr,omitempty"` + LeftFromText int `xml:"w:leftFromText,attr"` + RightFromText int `xml:"w:rightFromText,attr"` + VertAnchor string `xml:"w:vertAnchor,attr"` + HorzAnchor string `xml:"w:horzAnchor,attr"` + TblpX int `xml:"w:tblpX,attr"` + TblpY int `xml:"w:tblpY,attr"` +} + +// UnmarshalXML ... +func (tp *WTablePositioningProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) { + for _, attr := range start.Attr { + switch attr.Name.Local { + case "leftFromText": + tp.LeftFromText, err = strconv.Atoi(attr.Value) + if err != nil { + return err + } + case "rightFromText": + tp.RightFromText, err = strconv.Atoi(attr.Value) + if err != nil { + return err + } + case "vertAnchor": + tp.VertAnchor = attr.Value + case "horzAnchor": + tp.HorzAnchor = attr.Value + case "tblpX": + tp.TblpX, err = strconv.Atoi(attr.Value) + if err != nil { + return err + } + case "tblpY": + tp.TblpY, err = strconv.Atoi(attr.Value) + if err != nil { + return err + } + } + } + + // Consume the end element + _, err = d.Token() + return err +} + // WTableStyle represents the style of a table in a Word document. type WTableStyle struct { XMLName xml.Name `xml:"w:tblStyle,omitempty"` @@ -160,10 +230,7 @@ func (t *WTableStyle) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err } // Consume the end element _, err = d.Token() - if err != nil { - return - } - return nil + return err } // WTableWidth represents the width of a table in a Word document. @@ -193,10 +260,7 @@ func (t *WTableWidth) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err } // Consume the end element _, err = d.Token() - if err != nil { - return - } - return nil + return err } // WTableLook represents the look of a table in a Word document. @@ -306,10 +370,7 @@ func (g *WGridCol) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err err } // Consume the end element _, err = d.Token() - if err != nil { - return - } - return nil + return err } // WTableRow represents a row within a table. @@ -377,6 +438,7 @@ func (w *WTableRow) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { type WTableRowProperties struct { XMLName xml.Name `xml:"w:trPr,omitempty"` TableRowHeight *WTableRowHeight + Justification *Justification `xml:"w:jc,omitempty"` } // UnmarshalXML ... @@ -390,11 +452,11 @@ func (t *WTableRowProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElemen return err } - if elem, ok := tok.(xml.StartElement); ok { - switch elem.Name.Local { + if tt, ok := tok.(xml.StartElement); ok { + switch tt.Name.Local { case "trHeight": th := new(WTableRowHeight) - for _, attr := range elem.Attr { + for _, attr := range tt.Attr { if attr.Name.Local == "val" { th.Val, err = strconv.ParseInt(attr.Value, 10, 64) if err != nil { @@ -408,6 +470,19 @@ func (t *WTableRowProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElemen if err != nil { return err } + case "jc": + th := new(Justification) + for _, attr := range tt.Attr { + if attr.Name.Local == "val" { + th.Val = attr.Value + break + } + } + t.Justification = th + err = d.Skip() + if err != nil { + return err + } default: err = d.Skip() if err != nil { diff --git a/structtable_test.go b/structtable_test.go index 54d7a45..854c012 100644 --- a/structtable_test.go +++ b/structtable_test.go @@ -34,8 +34,9 @@ func TestTableStructure(t *testing.T) { para1 := w.AddParagraph() // add text para1.AddText("table") - tab1 := w.AddTable(4, 3) - para2 := tab1.TableRows[3].TableCells[2].AddParagraph() + tab1 := w.AddTable(4, 3).Justification("center") + tab1.TableProperties.Position = &WTablePositioningProperties{LeftFromText: 2333} + para2 := tab1.TableRows[3].Justification("center").TableCells[2].AddParagraph() r, err := para2.AddAnchorDrawingFrom("testdata/fumiama.JPG") if err != nil { t.Fatal(err)